Property

提到属性必然要理解Property了。

Property:(属性)是Objective-C的一项特性,用于封装对象中的数据。

  • Objective-C对象通常会把其所需要的数据保存为各种实例变量。

先理解下实例变量

  • 实例变量:属性是用变量来表示的,这种变量就称为实例变量。是在类声明的内部但是在类的其他成员方法之外声明的。一般通过”存取方法”来访问。
1
2
3
4
5
6
7
8
9
10
// 比如定义一个 NSString类型 的属性 strongedStr。
@interface Test_ViewController ()

@property NSString * strongedStr;

@end

// 当我们要调用这个strongedStr属性时系统会自动帮我们生成一个实例变量`_ strongedStr` 已经对应的setter和get方法

_strongedStr = @"";
  • 此处还需理解下self._。因为平时写代码最常见不过了,然后却从未理解过两者之间的区别。

采用self.xx访问的属性,在方法引用上是包含了set和get方法的。而通过_则不包含set和get方法。

因为self.xx是对属性的的访问而_是对局部变量的访问。
所以被声明为属性的成员在iOS5之前需要使用编译指令@synthesize来告诉编译器帮助生成属性的get和set方法,之后这个指令可以不用指定了,默认情况下编译器会帮我们生成。

编译器在生成get和set方法时存在优先级,首先会查找当前类中用户是否定义了属性的get和set方法。如果有则编译器会直接跳过,不会再生成get和set方法。

使用self.xx可以兼容懒加载,同时也避免了在使用_时对self指针的忽略。而且_容易在block中造成循环引用,甚至获取不到父类的属性,因为_只是对局部变量的访问。

总结: 在此建议在在读取实例变量的时候采用直接访问的形式即_,而在设置实例变量的时候则通过self.


  • 在使用属性时更为关注的就是其各种特质:原子性、读/写权限、内存管理语义、方法名。这也是为什么在讲完属性关键字后要在来讲属性的重要原因。

原子性: atomic、nonatomic

读/写权限: readwrite、readonly

内存管理语义: assign、strong、weak、unsafe_unretained、copy

方法名: getter、setter方法

  • 这里需要注意的是原子性,因为默认是atomic。而atomic是比较耗性能的,所以务必在非必要的情况下注明为nonatomic

理解完实例变量再来了解下成员变量

1
2
3
4
5
6
7
8
9
10
@interface Test_ViewController ()
{
NSString *string;
NSArray *array;
NSDictionary *dictionary;
}

@property (nonatomic, copy) NSString *name;

@end

简单理解{}中的就是成员变量,实例变量本质上也就是成员变量。成员变量用于类内部,无需与外界接触的变量。因为成员变量不会生成set get方法,既然没有get、set而且只用于类的内部所有外界自己不能与之接触。

  • 由此可以推断出 @property = 成员变量 + getter方法 + setter方法

property的关键知识点应该是其各种特质,不同的属性特质产生了不同的属性。因此掌握属性的特质是必不可少。