美文网首页
assign、copy、retain、nonatomic、ato

assign、copy、retain、nonatomic、ato

作者: 有人很斯文 | 来源:发表于2016-12-20 16:06 被阅读0次

1)一句话介绍

assign:     简单的赋值,不改变引用计数。(NSInteger 、int、 float、 char ...) 

copy:       开辟新的内存,新建一个索引计数为1的对象,可释放旧对象。(NSString)

retain:     是说明该属性在赋值的时候,先release之前的值,然后再赋新值给属性,引用再加1。

readonly:   该对象只能读取,不能改写,只生成getter方法,不会生成setter方法。

readwrite:  可读可写的对象。

nonatomic:非原子性访问,不加同步,多线程并发访问会提高性能。

2)换句话说 assign  and retain 有啥区别?

现在有这样一个场景,我分配了一块内存,并且把它的地址赋值给A指针。后来,我希望B指针也可以共享这块内存,于是乎,我又把A指针(内存地址)赋值给了B,这时候咧,A和B就同时拥有这块内存。

好了,

@property  (assign, nonatomic) 类型名* A;

@property  (retain, nonatomic) 类型名* B;

A =[ [ 类型名 alloc] init ] ;  B = A ;

Q:请问当A不再需要这块内存,能否直接释放它?

A:  答案是否定的,因为A并不知道B是否还在使用这块内存,如果A释放了,那么B在使用这块内存的时候会引起程序crash掉。

Q:  那么如何解决?

A:  最简单的一个方法就是使用引用计数(reference counting)。我们给那块内存设一个引用计数,当内存被分配并且赋值给A时,引用计数是1。当把A赋值给B时引用计数增加到2。这时如果A不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。B不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。

总的来说:assign就是直接赋值,从而可能引起上面的问题,当数据为int, float等原生类型时,可以使用assign。retain使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

3)换句话说 copy 到底怎么用?

copy:是在你不希望A和B共享一块内存时会使用到。A和B各自有自己的内存。

NSString、NSArray、NSDictionary等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,为确保对象中的属性值不会无意间变动,应该在设置新属性值时拷贝一份,保护其封装性

block也经常使用copy关键字

block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.

在ARC中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但是建议写上copy,因为这样显示告知调用者“编译器会自动对 block 进行了 copy 操作”

4)nonatomic 和 atomic 的又怎么说?

【摘自网络 侵删】

atomic:默认是有该属性的,这个属性是为了保证程序在多线程情况下,编译器会自动生成一些互斥加锁代码,避免该变量的读写不同步问题。

nonatomic:如果该对象无需考虑多线程的情况,请加入这个属性,这样会让编译器少生成一些互斥加锁代码,可以提高效率。

atomic的意思就是setter/getter这个函数,是一个原语操作。如果有多个线程同时调用setter的话,不会出现某一个线程执行完setter全部语句之前,另一个线程开始执行setter情况,相当于函数头尾加了锁一样,可以保证数据的完整性。nonatomic不保证setter/getter的原语行,所以你可能会取到不完整的东西。因此,在多线程的环境下原子操作是非常必要的,否则有可能会引起错误的结果

-  (void)setCurrentImage:(UIImage *)currentImage{

           NSLock *lock = [[NSLock alloc]init];

           [lock lock];

          if (_currentImage != currentImage) {

                      [_currentImage release];

                     _currentImage = [currentImage retain];

                   // do something

}

}

可以看出来,用atomic会在多线程的设值取值时加锁,中间的执行层是处于被保护的一种状态,atomic是oc使用的一种线程保护技术,基本上来讲,就是防止在写入未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

相关文章

网友评论

      本文标题:assign、copy、retain、nonatomic、ato

      本文链接:https://www.haomeiwen.com/subject/yctfvttx.html