assign
: 直接赋值,一般常用于基本数据类型(非 OC 对象),常见委托设计模式,一次来防止循环引用。不更改索引计数(Reference Counting)。 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char, 等等)retain
:计数+1,release
旧值,retain
新值, 获得到了对象的所有权,引用计数在原有基础上+1.释放旧的对象,将旧对象的值赋予输入对象,再增加输入对象的索引计数为1 。copy
: 计数+1,release
旧值,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
就是直接赋值,当数据为int, float等原生类型时,可以使用assign
。retain
,使用了引用计数,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等等一类的对象。
- 面试题:写一个
setter
方法用于完成@property(nonatomic, retain) NSString *name
,写一个setter
方法用于完成@property(nonatomic, copy) NSString *name
?
// 在 MRC 下,再次调用 set 方法需要注意先释放掉当前的变量
- (void)setName:(NSString *)str {
// 需要确保新赋值的 str和之前的 name 不同,相同的话,通过释放 name,会造成野指针
if (name != str) {
[name release]; // 释放掉原先的变量,对原先的变量做 release 操作
name = [str retain];// 对新房间做一个 retain 操作
}
}
- (void)setName:(NSString *)str {
if (name != str) {
[name release];
name = [str copy];
}
}
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
是一个非常好的选择。