首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Swift教程之属性详解(3)

Swift教程之属性详解(3)

类StepCounter声明了一个Int类型的、含有willSet和didSet观察者的存储属性totalSteps。当这个属性被赋予新值时,willSet和didSet将会被调用,即使新值和旧值是相同的。
例子中的willSet观察者为参数起了个新的名字newTotalSteps,它简单地打印了即将被设置的值。
当totalSteps值被更新时,didSet观察者被调用,它比较totalSteps的新值和旧值,如果新值比旧值大,就打印所增加的步数。didSet并没有为旧值参数命名,在本例中,将会使用默认的名字oldValue来表示旧的值。
注意
如果通过didSet来设置属性的值,即使属性值刚刚被设置过,起作用的也将会是didSet,即新值是didSet设置的值
4、全局和局部变量
以上所写的关于计算与观察属性值的特性同样适用于全局和局部变量。全局变量是在任何函数、方法、闭包、类型上下文外部定义的变量,而局部变量是在函数、方法、闭包中定义的变量。
前面章节所遇到过的全局、局部变量都是存储变量。和存储属性一样,存储变量为特定类型提供存储空间并且可以被访问
但是,你可以在全局或局部范围定义计算变量和存储变量观察者。计算变量并不存储值,只用来计算特定值,它的定义方式与计算属性一样。
注意
全局常量和变量通常是延迟计算的,跟懒惰存储属性一样,但是不需要加上@lazy。而局部常量与变量不是延迟计算的。
5、类型属性
实例属性是特定类型实例的属性。当创建一个类型的实例时,这个实例有自己的属性值的集合,这将它与其它实例区分开来。
也可以定义属于类型本身的属性,即使创建再多的这个类的实例,这个属性也不属于任何一个,它只属于类型本身,这样的属性就称为类型属性。
类型属性适用于定义那些特定类型实例所通用的属性,例如一个可以被所有实例使用的常量属性(就像c中的静态常量),或者变量属性(c中的静态变量)。
可以为值类型(结构、枚举)定义存储类型属性和计算类型属性。对类而言,只能够定义计算类型属性。
值类型的存储类型属性可以是常量也可以是变量。而计算类型属性通常声明成变量属性,类似于计算实例属性
注意
不想存储实例属性,你需要给存储类型属性一个初始值。因为类型本身在初始化时不能为存储类型属性设置值
类型属性句法
在C和Objective-C中,定义静态常量、变量和全局静态变量一样。但是在swift中,类型属性的定义要放在类型定义中进行,在类型定义的大括号中,显示地声明它在类型中的作用域。
对值类型而言,定义类型属性使用static关键字,而定义类类型的类型属性使用class关键字。下面的例子展示了存储和计算类型属性的用法:
[url=]复制代码[/url] 代码如下:

struct SomeStructure {
static var storedTypeProperty = "Some value."
static var computedTypeProperty: Int {
// return an Int value here
}
}
enum SomeEnumeration {
static var storedTypeProperty = "Some value."     static var computedTypeProperty: Int {     // return an Int value here
}
}
class SomeClass {
class var computedTypeProperty: Int {
// return an Int value here
}
}

注意
上面的例子是针对只读计算类型属性而言的,不过你也可以像计算实例属性一样定义可读可写的计算类型属性
查询与设置类型属性
像实例属性一样,类型属性通过点操作符来查询与设置。但是类型属性的查询与设置是针对类型而言的,并不是针对类型的实例。例如:
[url=]复制代码[/url] 代码如下:

println(SomeClass.computedTypeProperty)
// prints "42"
println(SomeStructure.storedTypeProperty)
// prints "Some value."
SomeStructure.storedTypeProperty = "Another value."
println(SomeStructure.storedTypeProperty)
// prints "Another value.

下面的例子在一个结构中使用两个存储类型属性来展示一组声音通道的音频等级表。每个通道使用0到10来表示声音的等级。
从下面的图表中可以看出,使用了两组声音通道来表示一个立体声音频等级表。当一个通道的等级为0时,所有的灯都不会亮,当等级为10时,所有的灯都会亮。下面的图中,左边的通道表示声音等级为9,右边的为7

上述的声音通道由以下的AudioChannel结构实例来表示:
[url=]复制代码[/url] 代码如下:

struct AudioChannel {
static let thresholdLevel = 10
static var maxInputLevelForAllChannels = 0
var currentLevel: Int = 0 {
didSet {
if currentLevel > AudioChannel.thresholdLevel {
//cap the new audio level to the threshold level
currentLevel = AudioChannel.thresholdLevel
}
if currentLevel > AudioChannel.maxInputLevelForAllChannels {
// store this as the new overall maximum input level
AudioChannel.maxInputLevelForAllChannels = currentLevel
}
}
}
}

AudioChannel结构定义了两个存储类型属性。thresholdLevel定义了音频所能达到的最高等级,对所有的AudoChannel实例而言,是个值为10的常量。当一个声音信号的值超过10时,会被截断为其阈值10。
第二个类型属性是一个变量存储属性maxInputLevelForAllChannels。它保存了当前所有AudioChannel实例中所接受到声音的最高等级,它被初始化为0。
结构还定义了一个存储实例属性currentLevel,表示当前的通道声音等级。这个属性使用didSet属性观察者来检测currentLevel的改变。这个观察者执行两道检查:
如果currentlevel的新值比阈值thresholdLevel大,currentLevel将被设置成thresholdLevel
如果currentLevel的新值比所有AudioChannel实例之前接受到的最大声音等级还要大,那么maxInputLevelForAllChannles将会被设置成cueentLevel大值。
继承事业,薪火相传
返回列表