property属性
提供成员变量的访问方法的声明、控制成员变量的访问权限、控制多线程时成员变量的访问环境。
property不但可以在interface,在协议protocol.和类别category中也可以使用。
synthesize 合成访问器方法
实现property所声明的方法的定义。其实说直白就像是:property声明了一些成员变量的访问方法,synthesize则定义了由property声明的方法。
他们之前的对应关系是:property 声明方法 ->头文件中申明getter和setter方法 synthesize定义方法 -> m文件中实现getter和setter方法。
在Xcode4.5及以后的版本中,可以省略@synthesize,编译器会自动帮你加上get 和 set 方法的实现,并且默认会去访问_age这个成员变量,如果找不到_age这个成员变量,会自动生成一个叫做 _age的私有成员变量。在.m文件中同时实现getter和setter时候需要@synthesize age = _age.
1.读写特性:readonly 、readwrite
在Objective-C中,拥有这样两个读写特性:readwrite和readonly,意思简单明了,就是可读可写以及只读。默认情况下,属性默认是可读可写的。
2.setter语意
setter语意特性主要是用来告诉Xcode,对于这个属性,应该如何去自动实现它的setter方法。这个特性主要是针对非ARC情况的。
在Objective-C中,拥有三个setter语意特性:assign、retain和copy,默认情况下属性特性是assign的。
assign:简单赋值特性,它不会对索引计数(Reference Counting)进行更改。默认类型,setter方法直接赋值,而不进行retain操作
-(void)setStr:(NSString*)value{
str=value;
}
retain:setter方法释放(release)旧的对象,然后将旧对象的值赋予输入对象,再将输入对象的索引计数增加1(retain)。
-(void)setStr:(NSString*)v{
if(v!=str){
[str release];
str=[v retain];
}
}
copy:setter方法进行Copy操作,与retain一样,建立一个索引计数为1的对象,释放掉旧对象。
-(void)setStr:(NSString*)v{
if(v!=str){
[str release];
str=[v copy];
}
}
什么时候使用这些语意特性呢?
只要是值类型、简单类型的类型,比如说NSInteger、CGPoint、CGFloat,以及C数据类型int、float、double等,都应该使用assign。
那么对于含有可深复制子类的对象,比如说NSArray、NSSet、NSDictionary、NSData、NSString等等,都应该使用copy特性。
注意:对于NSMutableArray之类的可变类型,不能够使用Copy特性,否则初始化会出现错误。
至于其他的NSObject对象,那么都应该使用retain来进行操作,这也是绝大多数所使用的情况。
3.所有者特性
对于ARC来说,上一节中所说的getter语意特性将被所有者特性所代替。
在Objective-C中,拥有两个所有者特性:strong和weak。默认情况下属性特性是strong的。
对于strong来说,它就相当于getter语意特性中的retain特性,即这个特性的属性将会成为对象的持有者。这个特性称之为强引用。
@property(strong) MyClass *myObject;
相当于@property(retain) MyClass *myObject;
对于weak来说,它声明的属性不会拥有这个对象的所有权,如果弱引用指向的对象被deallocated的话,弱引用的对象会被自动设置为nil。
@property(weak) MyOtherClass *delegate;
相当于@property(assign) MyOtherClass *delegate;
简单讲strong等同retain
weak比assign多了一个功能,当对象消失后自动把指针变成nil,好处不言而喻。
强引用与弱引用的广义区别:
强引用也就是我们通常所讲的引用,其存亡直接决定了所指对象的存亡。如果不存在指向一个对象的引用,并且此对象不再显示列表中,则此对象会被从内存中释放。
弱引用除了不决定对象的存亡外,其他与强引用相同。即使一个对象被持有无数个若引用,只要没有强引用指向他,那麽其还是会被清除。
面对ARC机制中,最令人头疼的就是“循环强引用”的问题,所谓循环强引用,就是我们申请了两个保险柜,然后分别将另外一个保险柜的钥匙锁在了保险柜当中。这样就会造成什么现象呢?我们完全就无法归还钥匙了,这两个保险柜就无法再重新使用了。那么使用弱引用,就不会出现这个问题了。
weak常用于网络delegate属性
原子特性
原子特性,简要来说,是针对多线程而设置的。Objective-C拥有两种原子特性,分别是atomic和nonatomic。
我们知道,如果使用多线程的话,有时会出现两个线程互相等待而导致的死锁现象。使用atomic特性,Objective-C可以防止这种线程互斥的情况发生,但是会造成一定的资源消耗。这个特性是默认的。
而如果使用nonatomic,就不会有这种阻止死锁的功能,但是如果我们确定不使用多线程的话,那么使用这个特性可以极大地改善应用性能。
相比之下,swift目前还不支持这些特性。如果我们要实现线程安全,似乎只能使用objc_sync_enter此类的方法,来保证属性的处理只有一个线程在进行。或者使用属性观察器来完成这些操作。
总结
我们总共介绍了四种属性特性,分别是读写特性、setter语意特性、所有者特性和原子特性。ARC是不支持setter语意特性的,它使用所有者特性。
网友评论
1.atomic在单核cpu中可以保证读写安全,在多核cpu中不管用的,一.因为可能会有多个响应在不同的线程对同一个变量调用setter方法.二.在单个响应的同时,可能有另一个周期性的任务,在另一个线程也调用了setter方法,在同一个时间点,不同的时间片,调用setter方法
2.要保证setter方法安全的,须手动加锁,例如NSLock,NSRecurisiveLock,NSConditon等
实现property的setter和getter方法就可以在类别中使用属性了.引用FDTemplateLayoutCell的代码:
- (BOOL)fd_isTemplateLayoutCell {
return [objc_getAssociatedObject(self, _cmd) boolValue];
}
- (void)setFd_isTemplateLayoutCell:(BOOL)isTemplateLayoutCell {
objc_setAssociatedObject(self, @selector(fd_isTemplateLayoutCell), @(isTemplateLayoutCell), OBJC_ASSOCIATION_RETAIN);
}