iOS开发-retain/assign/strong/weak/copy/mutablecopy/autorelease区别

readwrite:可读可写特性,需要生成getter和setter方法;

readonly:只读特性,只会生成getter方法,不会生成setter方法,不希望属性在类外改变时候使用;

alloc:对象分配后引用计数为1;

copy:一个对象变成新的对象(新内存地址) 引用计数为1,原来对象计数不变;

assign:是赋值特性,setter方法将传入参数赋值给实例变量(一把钥匙,同进同出),用于基础数据类型;

weak:由ARC引入的对象变量的属性,比assign多了一个功能,对象消失后把指针置为nil,避免了野指针(不是null指针,是指向“垃圾”内存(不可用的内存)的指针);

retain:表示持有特性,setter方法将传入参数先保留,后赋值(两把钥匙,各自进出),传入参数的retaincount加1;

strong:ARC引入,等同于retain;

copy:表示赋值特性,setter方法将传入对象复制一份;需要完全一个新的对象时候(两套房子,两把钥匙);

nonatomic:非原子操作,决定编译器生成setter和getter方法是否原子操作,不加同步,多线程访问提高性能;

__unsafe_unretain:对象引用不会加1,对象释放后,不会置为nil,可能造成野指针,尽量少用;

autorelease:对象引用计数-1 如果为0不马上释放,最近一个个pool时释放。

成员变量与属性

实际情况并非上面那么简单,你可能需要在一个函数里调用另一个函数分配的变量这时候有两个选择: 类成员变量和使用属性

@interface TestMem: NSObject {
  TestObject *m_testObject ; // 成员变量
  TestObject *testObject;    //成员变量
}

成员变量与上面的内存管理是一致的,只是在不同的函数里要保持引用计数加减的平衡所以要你要每次分配的时候检查是否上次已经分配了。是否还能调用
什么时候用属性?
1. 把成员做为public.
2. outlet 一般声明为属性(这个内存于系统控制,但我们还是应该做一样操作,后面会讲)
3. 如果很多函数都需要改变这个对象 ,或这个函数会触发很多次,建议使用属性。我们看看属性函数展开后是什么样子:

 1 // assign  
 2 -(void)setTestObject :(id)newValue{  
 3   testObject= newValue;  
 4 }  
 5 // retain  
 6 -(void)setTestObject :(id)newValue{  
 7   if (testObject!= newValue) {  
 8     [testObject release];  
 9     testObject= [newValue retain];  
10   }  
11 }  
12 // copy  
13 -(void)setTestObject :(id)newValue{  
14   if (testObject != newValue) {  
15     [testObject release];  
16     testObject = [newValue copy];  
17   }  
18 }

asssign 相当于指针赋值,不对引用计数进行操作,注意原对象不用了,一定要把这个设置为nil
retain 相当于对原对象的引用计数加1
copy 不对原对象的引用计数改变,生成一个新对象引用计数为1
注意:
self.testObject 左值调用的是setTestObject 方法. 右值为get方法,get 方法比较简单不用说了
而真接testObject 使用的是成员变量
self.testObject = [[testObject alloc] init]; // 错 reatin 两次
testObject = [NSArray objectbyindex:0];  // 错 不安全,没有retain 后面release会出错
如果testObject已有值也会mem leak

自动管理对象

iOS 提供了很多static(+) 创建对象的类方法,这些方面是静态的,可以直接用类名
调用如:
NSString *testString = [NSString stringWithFormat:@"test" ];
testString 是自动管理的对象,不用relese ,它有一个很大的retain count, release后数字不变。


例外

有一些通过alloc 生成的对象相同是自动管理的如:
NSString *testString = [[NSString alloc] initWithString:@"test1"];
retain count 同样是很大的数,没办法release
但为了代码对应,还是应该加上[ testString release];

不然xcode的Analyze 会认为内存leak, 但Instruments leak 工具检测是没有的。

posted @ 2014-05-10 23:35  激情为梦想而生  阅读(146)  评论(0编辑  收藏  举报