关于retain,assign,copy,strong,weak的见解

如果有错误的地方,请指正。

首先这里涉及到iOS的内存管理机制,大致来讲就是有申请就必定要有释放,在mrc状态下,如果使用alloc init等创建对象,其对象内部的引用计数器就会加1,你就必须要进行一次release,然后系统会在dealloc中自动释放。


assign--基础数据类型,简单赋值,引用计数器不变化。

retain--引用计数器加1,一般用于NSString和基础数据类型以外的类对象创建,他的含义是浅拷贝,也就是拷贝对象指针,但不拷贝内部内容,指针所指内容是一致的。

copy--引用计数器加1,一般用于nsstring,指深拷贝,也就是拷贝对象的内容和指针,消除旧对象。

strong--arc机制下的强指针引用,引用计数器加1,他的含义约等于retain。

weak-arc机制下的弱指针,所有指向这个对象的weak指针都将被置为nil,能避免因为意外释放而导致的carsh。

那么在一般声明控件时,假若是ib控件,则默认为weak状态,如果非ib状态下进行声明,则具体代码如下

@interface AController : UIViewController


{


    __weak UIView *aView;


}



@end




@implementation AController


- (void) viewDidLoad


{


    [super viewDidLoad];


    


    UIView *view = [[UIView alloc]initWithFrame:CGRectZero];


    [self.view addSubview:view];


    aView = view;


}



@end


基本还用weak声明,因为Controller并不直接“拥有”控件,控件由它的父view“拥有”。使用weak关键字可以不增加控件引用计数,确保控件与父view有相同的生命周期。

控件在被addSubview后,相当于控件引用计数+1;父view销毁后,所有的子view引用计数-1,则可以确保父view销毁时子view立即销毁。weak的控件在removeFromSuperview后也会立即销毁,而strong的控件不会,因为Controller还保有控件强引用。

在控件addSubview后再对weak变量赋值,防止控件被立即释放。



下面再来个例子,比如为什么NSString一般用copy而不用retain或者strong。
例子是摘抄别人的,懒得再打

@property (retain,nonatomicNSString *rStr;

@property (copynonatomic)   NSString *cStr;

- (void)test:

{

    NSMutableString *mStr = [NSMutableStringstringWithFormat:@"abc"];

    self.rStr   = mStr;

    self.cStr     = mStr;

    NSLog(@"mStr:%p,%p",  mStr,&mStr);

    NSLog(@"retainStr:%p,%p"_rStr, &_rStr);

    NSLog(@"copyStr:%p,%p",   _cStr, &_cStr);

假如,mStr对象的地址为0x11,也就是0x11是@“abc”的首地址,mStr变量自身在内存中的地址为0x123;

当把mStr赋值给retain的rStr时,rStr对象的地址为0x11,rStr变量自身在内存中的地址为0x124;rStr与mStr指向同样的地址,他们指向的是同一个对象@“abc”,这个对象的地址为0x11,所以他们的值是一样的。

当把mStr赋值给copy的cStr时,cStr对象的地址为0x22,cStr变量自身在内存中的地址0x125;cStr与mStr指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0x22,值为@“abc”。


如果现在改变mStr的值:

    [mStr appendString:@"de"];

    NSLog(@"retainStr:%@",  _rStr);

    NSLog(@"copyStr:%@",    _cStr);


结果,

使用retain的字串rStr的值:@"abcde",

而使用copy的字串cStr的值:@"abc",

所以,如果一般情况下,我们都不希望字串的值跟着mStr变化,所以我们一般用copy来设置string的属性。

如果希望字串的值跟着赋值的字串的值变化,可以使用strong,retain。

注意:上面的情况是针对于当把NSMutableString赋值给NSString的时候,才会有不同,如果是赋值是NSString对象,那么使用copy还是strong,结果都是一样的,因为NSString对象根本就不能改变自身的值,他是不可变的。


所以总的来说,NSString本身是无所谓的,但是如果一个 NSString 指针指向了一个 NSMutableString的内存空间的话,如果使用 strong 修饰的话,如果你在别处修改这个值的话,那么原来的值也会改变。用 copy 是生成了一份新的内存空间,原值不会改变,所以一般使用copy就足够了,因为我们很少有需求能跟随字符串变化而变化的字符串。



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值