一.@property中有哪些属性关键字
1.原子性/非原子性:atomic(默认)/nonatomic
nonatomic特质在默认情况下,由编译器合成的方法会通过锁定机制确保其原子性(atomicity)。如果属性具备 nonatomic特质,则不使用自旋锁。请注意,尽管没有名为“atomic”的特质(如果某属性不具备 nonatomic 特质,那它就是“原子的” (atomic) ),但是仍然可以在属性特质中写明这一点,编译器不会报错。若是自己定义存取方法,那么就应该遵从与属性特质相符的原子性。
2.读/写权限---readwrite(读写<默认>)、readonly (只读)
3.内存管理---assign、strong、weak、unsafe_unretained、copy(下文详细讲解)
4.方法名---getter=、setter=
getter=的样式:
@property (nonatomic, getter=isOn)BOOL on;
二.strong关键字分析
首先引用计数的理论就不详细阐述了,想了解了去看看唐巧大神的文章
http://blog.devtang.com/2016/07/30/ios-memory-management/
strong修饰的属性会对指向的对象进行强引用,大部分属性都需要用strong,不能用strong修饰的下来会具体讲解。
三.weak关键字分析
weak修饰的属性会对指向的对象进行强引用。weak使用的场景不多
场景1: 当使用xib/storyboard等拖拽的控件使用weak修饰。因为xib/storyboard已经将控件添加到view上了,所以已经进行了一次强引用了,没必要再使用strong修饰。
场景2: 解决循环引用,最常见的就是delegate的修饰。
举个例子来说,两个 VC A 和 B,VC A 需要弹出 VC B,让用户输入一些内容,当用户输入完成后,VC B 需要将内容返回给 VC A。这个时候,VC B 的 delegate 成员变量通常是一个弱引用,以避免两个 ViewController相互引用对方造成循环引用问题,如下所示:
扩展:解决这种循环引用除了使用weak,另一种办法:根据具体业务逻辑在不需要使用a对象的时候,主动断开引用。代理方法执行完后,主动断开VC B.delegate = nil;
主动断开循环引用这种操作依赖于程序员自己手工显式地控制,相当于回到了以前 “谁申请谁释放”的内存管理年代,它依赖于程序员自己有能力发现循环引用并且知道在什么时机断开循环引用回收内存(这通常与具体的业务逻辑相关),所以这种解决方法并不常用,更常见的办法是使用弱引用(weak reference) 的办法。
weak弱引用实现原理:
弱引用的实现原理是这样,系统对于每一个有弱引用的对象,都维护一个表来记录它所有的弱引用的指针地址。这样,当一个对象的引用计数为 0 时,系统就通过这张表,找到所有的弱引用指针,继而把它们都置成 nil。
从这个原理中,我们可以看出,弱引用的使用是有额外的开销的。虽然这个开销很小,但是如果一个地方我们肯定它不需要弱引用的特性,就不应该盲目使用弱引用。举个例子,有人喜欢在手写界面的时候,将所有界面元素都设置成weak 的,这某种程度上与 Xcode 通过 Storyboard 拖拽生成的新变量是一致的。但是我个人认为这样做并不太合适。因为:
1.我们在创建这个视图对象时,因为 weak 变量并不持有对象,就会造成一个对象刚被创建就销毁掉。
2.大部分 ViewController 的视图对象的生命周期与 ViewController 本身是一致的,没有必要额外做这个事情。
示例测试:
分析:因为testView属性使用的weak修饰,所以并不持用对象,那么这个对象并没有谁去指向它,所以这个视图对象刚创建就就销毁了,所以使用weak的修饰的时候就不能这样写了,需要用临时变量去指向这个视图对象。
修改如下
四.assign关键字
assgin用于修饰基本数据类型NSInterger, float, int等属性。