小谈@property的特质

2017-01-13 14:56:09来源:http://www.jianshu.com/p/f04a23d1c1b1作者:韶华笑人点击

第七城市

熟悉OC的小伙伴都会经常用到property(属性),属性是OC语言的一种特性,主要作用是封装对象中的数据,OC对象通常会把所需要的数据保存为各种实例变量。实例变量一般通过存取方法(access method)来访问。
使用属性时又一个问题需要注意:就是属性后面会经常附带一些特质(attribute),区分好每一种特质的作用是非常必要的。
例如下面的代码就有三种特质:


@property (nonatomic, copy, readonly) NSString * aString;

属性的特质主要分为以下四类:
1.原子性

在默认情况下,由编译器所合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备nonatomic特质,则不需要使用同步锁。与nonatomic对应的是atomic。注意:尽管没有命名为atomic的特质,扔可以在属性的特质中写atomic的声明,编译器也不会报错。若是自己定义属性的存取方法,就应该遵循属性的特质。
具备atomic特质的属性的获取方法会通过锁定机制来确保其操作的原子性。也就是说,如果有两个线程读写同一个属性,那么不论何时都能有效的属性值。如果时nonatomic特质(不加锁)的属性,当其中一个线程在改写值时,另一个线程也会突然闯入,把尚未修改好的属性值读取出来,这种情况下读取出来的值有可能是错误的。但是atomic特质会对系统能耗较大,属性常用nonatomic,也是默认的特质。


2.读/写权限
读&写:具备readwrite特质的属性拥有获取方法(getter)设置方法(setter),如果属性由@synthesize实现,则编译器会自动生成这两个方法(虽然再Xcode中看不见,但是可以直接使用)
只读:具备readonly特质的属性将只拥有获取方法(getter),只有在属性由@synthesize实现时,编译器才会为其合成获取方法。
3.内存管理

属性用于封装数据,而数据需要有具体的所有权语义(concrete ownership semantic),下面这些会影响属性的设置方法(setter)


assign 设置方法只会执行针对`纯量类型·(比如:NSInteger,CGFloat,int等)的操作。

strong 此特性表明了属性定义了一种拥有关系(owning relationship)。为这种属性设置新的值时,设置方法会先保留新值,并释放旧值,然后再将新值赋值上去。
    - (void)setName:(NSString *)newName {
NSString *tmp = newName;
[_oldName release];
_oldName = tmp;
}


weak 此特质表明了属性定义了一种非拥有关系(nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值也不释放旧值。此特质与assign 类似,然而在属性所对应的对象被释放时,属性的值会设置为nil



unsafe_unretaind 此特质的定义与assign特质相同,不同的是它适用于对象类型(object type),该特质表明了一种不保留关系(unretained),当所指对象被释放时,属性不会自动设置为nil(不安全 unsafe),这一点与weak区分。



copy 此特质所表达的所属关系与strong类似,不同的是其设置方法不会保留新值,而是将新值拷贝(copy)。属性类型是NSString时经常用此特质来保护其封装性,因为传递给设置方法的新值可能指向一个NSMutableString类的实例,此时如果不拷贝字符串,那么设置完属性之后,字符串的值可能在对象不知情的情况下被人修改。所以此时需要拷贝(copy)一份不可变的字符串,确保对象中的值不会不经意间变动。只要实现属性所用的对象是可变的,就应该在设置新值时拷贝(copy)一份。



4.方法名

可通过如下特质来制定获取方法设置方法的名称。


getter=<name> 此特质用来指定获取方法的名称。如果属性时BOOL值,而你想为其获取方法加上is前缀,就可以用这个特质来指定,编译器就会为你合成获取方法
@prpperty (getter=isAuth) BOOL auth;

setter=<name> 此特质涌来指定设置方法的名称,用的不常见。

over。




第七城市

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台