属性定义
@interface Nothin : NSObject
@property NSString *prop;
@end
访问属性
Nothin *nothin = [Nothin new];
//get
[nothin prop];
//set
[nothin setProp: @"Nothin"];
声明了@property后,编译器会自动整合属性的getter和setter
属性的访问方法命名规则:
getter方法和属性名相同, 例如prop 的getter方法名也为prop
setter方法是“set”前缀加上首字母大写的属性名, 例如prop 的setter方法名为 setProp
属性默认是readwrite的,给属性加readonly attribute:@property (readonly) NSString *prop
设置自定义的访问方法:@property (getter = getProp) NSString *prop;
如果同时设置多个attribute,用逗号分隔:@property (ready, getter = getProp) NSString *prop;
访问属性的简洁语法:
//get
NSString *str = nothin.firstName;
//set
nothin.firstName = @"Nothin";
默认情况下,编译器自动为属性封装了一个实例变量,实例变量是属性名加下划线前缀,例如prop属性封装的实例变量为 _prop
可以在类的内部直接访问该实例变量
- (void)Method
{
_prop = @"Nothin";
}
也可让属性封装自定义的实例变量,在.m 文件中,用synthesize关键字。例如:
@synthesize prop = custom_Prop;
如果用@synthesize 却没有给属性指定实例变量名,那么该属性封装的实例变量名就和属性名是一样的,例
@synthesize prop; 这种情况下实例变量的名字也为 prop
如果不想用属性来封装实例变量,也可以在.h或者.m中直接定义实例变量:
@interface Nothin : NSObject
{
NSString *_var;
}
默认情况下,属性是atomic的
@property NSString *prop; //隐式声明atomic
@property (atomic) NSString *prop; //显式声明atomic
atomic 意味着合成的访问方法保证完全通过getter获取值,完全通过setter来设置值,在多线程的情况下会比较有意义。如果对一个atomic的属性,不能把自定义的访问方法与默认的访问方法进行整合。例如对于readwrite的属性,只指定了自定义的setter,却没有指定自定义的getter,那么在编译时就会得到一个警告。
可以把一个属性设置成nonatomic,这样可以直接获取或者设置值,nonatomic的访问效率要比atomic快,但是在多线程访问的情况下可能会出问题。
@property (nonatomic) NSString *prop;
堆对象的引用关系默认是强引用的,比如在对象种声明一个属性
@interface Nothin : NSObject
@property NSString *prop
@end
那么Nothin对象就对 prop属性保持强引用,只有当Nothin对象被释放掉,prop属性不被其他任何对象引用,这种情况下prop才会成为垃圾,被回收掉
对象之间的强引用关系可能造成一个强引用循环,比如table view 类和它的delegate 之间的关系
这种情况下如果other objects都被释放掉,NSTableView 和Delegate Object也不会被释放,因为他们彼此保持强引用,不会被当作垃圾回收
避免强引用循环的解决方案是使用weak关键字,声明弱引用
这种情况下,NSTableView对Delegate Object弱引用,当引用Other Objects被释放掉后,Delegate Object没有其他对象对其强引用了,因此Delegate Object被释放,然后NSTableView也会被释放
声明弱引用属性
@property (weak) NSString *prop;
声明弱引用变量
NSString * __weak var;
如果一个对象被弱引用,那么当引用它的对象被释放掉,或者指向其他引用的情况下,被弱引用的对象就会被释放。
基础类库中有一些类不支持weak关键字,可以用unsafe_unretained关键字来代替weak
如果在对象中声明了一个强引用的属性,比如
@property NSString *prop;
//给prop赋值
NSMutableString *str = [NSMutableString stringWithString: @"Nothin"];
self.prop = str;
这个时候prop对str保持强引用,而str是可变的,当str的值变化后,prop的值会跟着变化
[str appendString:@"Garry"];
这时候 str的值为“NothinGarry”,而prop的值也变成了“NothinGarry”
为了避免这种情况,可以使用copy关键字
@property (copy) NSString *prop;
self.prop = str 这时候prop的值保存了str的副本,而不是str本身,以后str修改了,不会影响到prop的值
声明copy的属性类型必须要支持NSCopying方法