0x01 强引用与弱引用
当用指针指向某个对象时,你可以通过retain/release管理它的内存,也可以不管理。
如果你管理了,就拥有对这个对象的强引用(Strong Reference);
如果你没有管理,那么你拥有的就是弱引用(Weak Reference)。
强引用
1、firstName作为@”natsu”字符串对象的最初持有者,是该NSString类型对象的强引用;
2、这里将firstName的指针值传入aName中,即aName也成为了@”natsu”字符串对象的持有者,对于该对象,aName也是强引用;
3、改变firstName,指向新的字符串对象@”maki”。这时候firstName成为@”maki”的持有者,而@”natsu”的持有者只有aName。每个字符串对象都有各自的持有者,所以它们都在内存中存在;
4、追加新的变量otherName, 它将成为@”maki”对象的另一个持有者。即NSString类型对象的强引用;
5、将otherName的指针值传入aName,这时,aName将成为@”maki”字符串对象的持有者。而对象@”natsu”已经没有持有者了,该对象将被释放。
弱引用
1、与强引用方式一样,firstName作为字符串对象@”natsu”的持有者存在。即是该NSString类型对象的强引用;
2、使用关键字__weak,声明弱参照weakName变量,将firstName的指针值传递给它。这时weakName虽然指向@”natsu”,但仍是弱引用。即weakName虽然能看到@”natsu”,但不是其持有者;
3、firstName指向了新的对象@”maki”,成为其持有者,而对象@”natsu”因为没有了持有者,即被释放。同时weakName变量将被自动代入nil,这就是归零弱引用(Zeroing Weak Reference),能够避免出现野指针错误。
0x02 引用关键字
__strong
变量声明默认都带有__strong关键字,如果变量什么关键字都不写,那么就默认为强引用。
__weak
弱引用关键字__weak从 iOS 5 / Mac OS X 10.7 开始支持,严格来说应该叫归零弱引用(Zeroing Weak Reference)。
作用类似于assign,都可以将变量声明为弱引用,但是应强调weak的“归零”作用!!!
weak严格的说应当叫“ 归零弱引用 ”,即当对象被销毁后,会自动的把它的指针置为nil,这样可以防止野指针错误:
而assign销毁对象后不会把该对象的指针置nil,对象已经被销毁,但指针还在痴痴的指向它,这就成了野指针:
__unsafe_unretained
在低于 iOS 5 / Mac OS X 10.7 的版本中编译含有弱引用关键字__weak的代码,编译器会因为不支持ARC特性而报错,那就必须使用__unsafe_unretained关键字来声明弱引用。
__unsafe_unretained关键字作用相当于assign,它不执行归零操作,所以要注意野指针问题。
__autoreleasing
启用ARC后,不能向对象发送autorelease消息。当一个对象被赋值给一个使用__
autoreleasing修饰符修饰的指针时,相当于这个对象在MRC下被发送了autorelease消息,也就是说它被放到自动释放池中。
全局变量和实例变量不可用__
autoreleasing修饰。
典型应用就是当方法的参数是id*,且希望方法返回时对象被autoreleased,那就用__
autoreleasing修饰:
//MRC
-(NSString *)stringTest
{
NSString *retStr = [NSString stringWithString:@"test"];
return [[retStr retain] autorelease];
}
//ARC
-(NSString *)stringTest
{
__autoreleasing NSString *retStr = [NSString alloc] initWithString:@"test"];
return retStr;
}