iOS开发中的ARC内存管理机制(2)——强引用与弱引用

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;    
}    

猜你喜欢

转载自blog.csdn.net/qq_33737036/article/details/81273850