【iOS面试系列-1】iOS中@property 后assign,copy,retain,weak,strong的意义与区别(必考-必须详细掌握)

帅比萌擦擦* 提交于 2019-12-28 14:04:11

来源:网络

assign: 普通(简单)赋值,一般常用于基本数据类型,常见委托设计模式,一次来防止循环引用。不更改索引计数(Reference Counting)。 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)

retain:保留计数,获得到了对象的所有权,引用计数在原有基础上+1.释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 。我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到 2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。retain之后count加一。alloc之后count就是1,release就会调用dealloc销毁这个对象。如果 retain,需要release两次。通常在method中把参数赋给成员变量时需要retain。NSArray对象会retain(retain值加一)任何数组中的对象。当NSArray被卸载(dealloc)的时候,所有数组中的对象会 被 执行一次释放(retain值减一)。不仅仅是NSArray,任何收集类(Collection Classes)都执行类似操作。例如 NSDictionary,甚至UINavigationController。

copy: 建立一个索引计数为1的对象,然后释放旧对象 。用来复制对象,一般字符串用copy,Foundation中不可变对象使用copy效果相当于retain,只是引用计数+1.


autorelease 原理:

autorelease和作用域没有任何关系!
a.先建立一个autorelease pool
b.对象从这个autorelease pool里面生成。
c.对象生成 之后调用autorelease函数,这个函数的作用仅仅是在autorelease pool中做个标记,让pool记得将来release一下这个对象。
d.程序结束时,pool本身也需要rerlease, 此时pool会把每一个标记为autorelease的对象release一次。如果某个对象此时retain count大于1,这个对象还是没有被销毁。

记住一点:如果这个对象是你alloc或者new出来的,你就需要调用release。如果使用autorelease,那么仅在发生过retain的时候release一次(让retain count始终为1)。

 

在ARC中,

strong(强引用)告诉编译器自动帮我们插入retain,

weak(弱引用)是普通赋值相当于手动管理内存的assign。

-------------------------------------------------------------------------------------------------------------------------------------

区别

assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。

 

copy和retain

copy是创建一个新对象,copy是在你不希望a和b共享一块内存时会使用到。a和b各自有自己的内存,retain是创建一个指针,引用对象计数加1。Copy属性表示两个对象内容相同,新的对象retain count为1 ,与旧有对象的引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1也就是说,retain 是指针拷贝,copy 是内容拷贝。这里指的是NSString,NSNumber等等一类的对象。

 

weak 和strong的区别:

(weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会被释放  ,即使还有weak型指针指向它。

一旦最后一个strong型指针离去 ,这个对象将被释放,所有剩余的weak型指针都将被清除。

 

retain和strong的区别:在处理用strong声明的Block属性引发的问题时偶然发现的。在诸多教程中都会讲到:声明属性时用strong或者retain效果是一样的(貌似更多开发者更倾向于用strong)。不过在声明Block时,使用strong和retain会有截然不同的效果。strong会等于copy,而retain竟然等于assign!当然定义Block还是应该用copy(还有其他需要注意的地方,可以参考这篇文章:iOS: ARC和非ARC下使用Block属性的问题),因为非ARC下不copy的Block会在栈中,ARC中的Block都会在堆上的。(http://blog.csdn.net/lvxiangan/article/details/50729888    不知道真的假的)

 

assign和weak的区别:weak比assign多了一个功能,当对象消失后自动把指针变成nil。assign是指针赋值,不对引用计数操作,使用之后如果没有置为nil,可能就会产生野指针。当你的指针类型成员变量不需要进行强引用的时候,使用assign和weak都可以,比如一些delegate,否则使用strong
而基础类型只能使用assign,assigin 可以用非 OC 对象,而 weak 必须用于 OC 对象

 

block和weak区别

__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。

block对象可以在block中被重新赋值,weak不可以。

 

atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。 

 【理解:http://www.cnblogs.com/langtianya/p/3691035.html】

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!