您的位置:首页 > 大数据 > 人工智能

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

2016-05-16 21:07 435 查看
如果有错误的地方,请指正。

首先这里涉及到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的值:

    [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就足够了,因为我们很少有需求能跟随字符串变化而变化的字符串。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息