@property 的总结
@property 是一种支持访问对象成员变更的快捷方法,可以自动生成setter和getter方法。
面向对象思想的基本特点为封装、继承、多态。封装性主要体现在无法直接访问对象成员变量,如果需要的话,通过setter和getter方法访问成员变量。这样的话,通常要为每一个支持外边访问的成员变量写两个方法,这种操作比较繁琐且无意义。通过@property可以简化这种方法。
@property的修饰属性(attributes )
可读性:readwrite / readonly ,不写的话默认为readwrite,即会合成setter和getter方法。
原子性:nonatomic / 【默认】,系统默认setter和getter为原子操作(没有atomic关键字),如果想设置为非原子操作,可以nonatomic。
4,atomic//默认属性
A,当一个变量声明为atomic时,意味着在多线程中只能有一个线程能对它进行访问
B,当一个变量声明为atomic时,该变量为线程安全型,但是会影响访问速度,
C,当一个变量声明为atomic时,在非ARC编译环境下,需要设置访问锁来保证对该变量
进行正确的get/set
特点 : 单写多读
atomic 属性的setter里面里面有一把锁,叫做自旋锁
atomic :| 0:0 | 1:0 | | -- | -- | | 0:2 | 1:2 | 线程安全,需要消耗大量的资源.性能比非原子属性要差一点儿点儿.
自旋锁:如果发现有其他线程正在执行锁定的代码,线程会以死循环的方式,一直等待锁定代码执行完成.
nonatomic
A, 当一个变量声明为nonatomic时,意味着多个线程可以同时对其进行访问
B, 当一个变量声明为nonatomic时,它是非线程安全型,访问速度快;
C, 当一个变量声明为nonatomic时,当两个不同的线程对其访问时,容易失控。
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果
nonatomic : 非线程安全,适合内存小的移动设备.
互斥锁:如果发现有其他线程正在执行锁定的代码,线程会进入休眠状态,等待其他线程执行完毕,打开锁之后,线程会重新进入就绪状态.等待被CPU重新调度.
• 所有属性都声明为nonatomic,原子属性和非原子属性的性能几乎一样.
• 尽量避免多线程抢夺同一块资源.
• 要实现线程安全,必须要用到锁.无论什么锁,都是有性能消耗的.
• 自旋锁更适合执行非常短的代码.死循环内部不适合写复杂的代码.
• 尽量将加锁,资源抢夺的业务逻辑交给服务器端处理,减小移动客户端的压力.
• 为了流畅的用户体验,UIKit类库的线程都是不安全的,所以我们需要在主线程(UI线程)上更新UI.
• 所有包含NSMutable的类都是线程不安全的.在做多线程开发的时候,需要注意多线程同时操作可变对象的线程安全问题.
内存 assign / retain / weak / strong ,在非ARC环境下, assign为默认,引用计数不变;retain引用计数加1;在引用计数环境下,默认为strong,与retain作用相同;从5.0系统后引入了weak,作用与assign相似,不过当所指向对象引用为0时,自动置为nil。
copy:MRC下先release旧值,再copy新值,copy的本质为复制该内存所存储的内容,重新创建一个对象赋给其相同的内容,很明显,在copy这个过程中也发生了一次retain,不过这是个全新的对象。在上例中,_str与str最终指向了不同的内存区域,但其内容一样。
copy一般适用于NSString等不可变的对象,因为是重新创建了对象,并且内容不变,因此不用担心后面的操作会对该属性的值产生影响。