Swift中的计算属性/存储属性与OC中的@property
Swift中引入了存储属性、计算属性的概念,存储属性用于存储一些值或引用,计算属性则提供get/set方法处理其他的属性或逻辑操作,但get/set方法中没法对计算属性自身进行修改,否则会造成死循环。
OC中虽然没有存储属性和计算属性的概念,但@property
关键字实际上也间接的完成了存储属性+计算属性的自动创建。
@property (nonatomic, copy) NSString *aStr;
以上面的属性为例:
OC中的@property
关键字自动的帮我们生成了两个属性(这里是类比Swift的说法,实际以OC的说法是一个变量_aStr,还有get/set方法),一个是_aStr:存储属性->用于存储一个NSString,一个是aStr:计算属性->get方法返回_aStr、set方法对_aStr进行一些其他操作。
Swift中没有@property
关键字,一个属性如果想写成如下方式,实现get/set方法则是错误的:
// 错误的写法
var name: String? {
get {
return name
}
set {
name = newValue
}
}
如果写成上面的形式,编译器会报警告,在运行中,因为name在自己的get/set方法中操作name,本质还是调用name的get/set方法,所以最后肯定都是以陷入死循环而告终,所以计算属性就是用来计算的,不能用来存储,存储相关工作应该交给存储属性
。
那么跟OC相比,想实现理想的get/set方法,Swift中的这个计算属性name缺的是什么呢?那就是再加一个存储属性_name:
var _name: String?
var name: String? {
get {
return _name
}
set {
_name = newValue
}
}
这样一来,以上的Swift代码实现的功能就跟OC中的@property
实现的功能一样了。
@property、@synthesize、@dynamic
xcode4.4之前,如果用@property声明一个属性,实际上是配合着@synthesize来用的,@property生成get/set方法,@synthesize生成一个存储属性(现在@property已经默认实现了@synthesize所提供的功能):
// @interface中
@property (nonatomic, copy) NSString *name;
// @implementation中
@synthesize name = _name;
如果类比Swift中的存储属性、计算属性,@property与计算属性对应
、@synthesize与存储属性对应
,这样就很好理解了。