iOS IOS atomic与nonatomic,assign,copy与retain的定义和区别

来源:互联网 发布:开放记录数据在线查 编辑:程序博客网 时间:2024/04/19 18:16
1:atomic  和nonatomic 
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。
        atomic
                设置成员变量的@property属性时,默认为atomic,提供多线程安全。
                在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:
                        {lock}
                                if (property != newValue) { 
                                        [property release]; 
                                        property = [newValue retain]; 
                                }
                        {unlock}
        nonatomic
禁止多线程,变量保护,提高性能。

2:assign
       assign的作用:就是直接赋值,简单赋值。对基础数据类型 (NSInteger)和C数据类型(int,float,double,char,short,long,等)赋值(查看oc的数据类型)。它没有对引用计数加一的作用,所以一般不用assign对oc对象进行属性使用。
那为什么九中基础类型可以用assign呢
基础数据类型: 如short、int、double、long等他们不在【堆】中,可能在【全局区】也可能在【栈】中,根据他们定义的位置而定,而这些内存都是由系统自动管理的,不同于【堆】需要手动释放。所以基本数据类型可以使用assign来生成set方法直接进行赋值。
除却非基本数据类型是对象类型-包装类型时,这类数据一般都在【堆】中被创建,引用计数不正确,可能会导致严重的内存问题。如果要对对象使用assgin,这是赤裸裸的对Object C内存管理机制的挑战,这样做会使属性直接指向赋值者所指向的对象,既不对属性旧对象进行release操作,也不对新对象retain操作。
        此标记说明设置器直接进行赋值,这也是默认值。在使用垃圾收集的应用程序中,如果你要一个属性使用assign,且这个类符合NSCopying协议,你就要明确指出这个标记,而不是简单地使用默认值,否则的话,你将得到一个编译警告。这再次向编译器说明你确实需要赋值,即使它是可拷贝的。
        结果:iOS中的垃圾处理机制是根据一个对象的索引数来处理的,为0的时候表示没有地方使用该对象,则该对象将被清除,而基本数据类型不属于对象,它的创建和使用都是在内存中,超出对应方法体即被清除,所以不需要使用垃圾处理机制,无需记录索引值,所以使用assgin

3:retain
        对其他NSObject和子类对参数进行release旧值,再retain新值
        指定retain会在赋值时唤醒传入值的retain消息属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。
        注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。

4:copy
      对NSString 它指出此属性只对那些实行了NSCopying协议的对象类型有效
系统非容器:string和mutableSring
copy:                   string                       浅拷贝、指针拷贝
mutablecopy         string                         深拷贝、内容拷贝
copy:                  mutableString            深拷贝、内容拷贝
mutablecopy         mutableString            深拷贝、内容拷贝
系统容器类NSArray,NSDictionary
copy:                   array                        浅拷贝、指针拷贝
mutablecopy        array                         深拷贝、内容拷贝
copy:                  mutableArray            单层内容拷贝、单层深拷贝
mutablecopy        mutableArray            单层内容拷贝、单层深拷贝

更深入的讨论,看此copy

copy和strong的区别:
不得不说下copy和strong在复制时候的区别,此处不讲引用计数的问题。
copy:拷贝一份不可变副本赋值给属性;所以当原对象值变化时,属性值不会变化;
strong:有可能指向一个可变对象,如果这个可变对象在外部被修改了,那么会影响该属性;
比如在model赋值的时候声明属性,一般字符串我们都用copy,这样省内存并且不可修改,(如果model内容不改变的 情况下。)但是用strong的话就会被修改。看业务操作需求。

copy与retain
Copy其实是建立了一个相同的对象,而retain不是:
1.比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。
2.新的对象retain为1 ,旧有对象没有变化retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。
总结:retain 是指针拷贝,copy 是内容拷贝需要考虑到是什么拷贝。

assign和weak
assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针;而weak一旦不进行使用后,就会自己置为nil,所以就不会产生野指针!
copy   修饰string   block;  
strong 修饰其他oc对象比如array dictionary; 
weak 修饰的ui控件  代理属性 ;
assign 基本数据类型  比如cgfloat cgrect  
assign 就是赋值,所以大多用于基础类型,因为基础类型只需要赋值就可以了,如果用于指针类型,那么你就需要确定它不需要被引用持有了,在这种情况下,跟weak是一样的
weak 是弱引用,而基础类型不是指针,不能进行引用,所以会编译报错
总结:当你的指针类型成员变量不需要进行强引用的时候,使用assign和weak都可以,比如一些delegate,否则使用strong,而基础类型只能使用assign
assign此特质表明该属性定义了一种“非拥有关系” (nonowning relationship)。为这种属性设置新值时,设置方法既不保留新值,也不释放旧值。此特质同assign类似, 然而在属性所指的对象遭到摧毁时,属性值也会清空(nil out)。 而assign的“设置方法”只会执行针对“纯量类型” (scalar type,例如 CGFloat 或 NSlnteger 等)的简单赋值操作。weak特性要求不保留传入的对象。如果该对象被释放,那么相应的实例变量会被自动赋为nil。这么做可以避免产生悬空指针。悬空指针指向的是不再存在的对象。向悬空指针发送消息通常会导致程序崩溃。相应的存方法会将传入的对象直接赋给实例变量。
另: assigin 可以用非 OC 对象,而 weak 必须用于 OC 对象

assign与retain
1. 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。
2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。
总结:上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

strong和weak
一个对象用了strong,表明它被拥有了,比如:nsstrig *str = @“21”; 这里面默认就是strong(在arc环境下),weak的话就是表示随时都可以被释放。对它的关系不是拥有关系。  详细链接(weak和strong)
strong

        强引用,ARC模式下与retain同作用,对象的retaincount自动加1
week

        弱引用,ARC模式下与assign同作用,非对象类型使用。



注解
1:
Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能。下面列举该框架支持进行管理的数据以及可提供的服务:




阅读全文
0 0
原创粉丝点击