美文网首页
关于retain,assign,copy,strong,weak

关于retain,assign,copy,strong,weak

作者: AlenChen | 来源:发表于2016-06-17 20:51 被阅读66次

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

    首先这里涉及到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,nonatomic)NSString*rStr;

    @property(copy,nonatomic)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的值:

    [mStrappendString:@"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就足够了,因为我们很少有需求能跟随字符串变化而变化的字符串。

    相关文章

      网友评论

          本文标题:关于retain,assign,copy,strong,weak

          本文链接:https://www.haomeiwen.com/subject/jtvvdttx.html