天天看點

retain(strong)和copy之間的關系

#import "ViewController.h"

@interface ViewController ()

@property (retain,nonatomic) NSString *rStr;  //這裡的retain和strong是一樣的

@property (copy, nonatomic)   NSString *cStr;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    [self test];
}


- (void)test
{
    NSMutableString *mStr = [NSMutableString stringWithFormat:@"abc"];
    
    self.rStr = mStr;  //retain的方式就是引用指派
    self.cStr = mStr;  //cop有的方式就是深拷貝
    
    NSLog(@"mStr:%16p,%16p,%[email protected]", mStr,&mStr,mStr);
    NSLog(@"retainStr:%16p,%16p,%[email protected]", _rStr, &_rStr,_rStr);
    NSLog(@"copyStr:%16p,%16p,%[email protected]",   _cStr, &_cStr,_cStr);
    
    [mStr appendString:@"de"];
    NSLog(@"mStr:%16p,%16p,%[email protected]", mStr,&mStr,mStr);
    NSLog(@"retainStr:%16p,%16p,%[email protected]", _rStr, &_rStr,_rStr);
    NSLog(@"copyStr:%16p,%16p,%[email protected]",   _cStr, &_cStr,_cStr);
}
@end
           

運作之後的結果是:

retain(strong)和copy之間的關系

從上面結果我們可以看出:

 假如,mStr對象的位址為0x7ff3ea505f00,也就是0x11是@“abc”的首位址,mStr變量自身在記憶體中的位址為0x7fff59bd9b08;(這裡注意對象的位址和自身變量的位址)

 當把mStr指派給retain的rStr時,rStr對象的位址為0x7ff3ea505f00,rStr變量自身在記憶體中的位址為0x7ff3ea7366d8;rStr與mStr指向同樣的位址,他們指向的是同一個對象@“abc”,這個對象的位址為0x7ff3ea505f00,是以他們的值是一樣的。(注意:他們自身的變量的位址是不同的)

 當把mStr指派給copy的cStr時,cStr對象的位址為0x7ff3ea50b580,cStr變量自身在記憶體中的位址0x7ff3ea7366e0;cStr與mStr指向的位址是不一樣的,他們指向的是不同的對象,是以copy是深複制,一個新的對象,這個對象的位址為0x7ff3ea50b580,值為@“abc”。(也就是指派出來一份)

同時看到增加了字元串了之後,retain中的值也會修改,而copy中的值不會修改,是以我們定義這些基礎的變量,我們一般都是使用copy來定義。

拓展:

NSObject自帶的常用的對象有:NSNumber、NSString、NSArray、NSDictionary、NSMutableArray、NSMutableDictionay、NSMutableString,copy産生的對象時不可變的,mutableCopy産生的對象時可變的。

也就是上面的這些類,如果定義一個對象的時候,我們将會使用的是copy或者mutableCopy來定義。

繼續閱讀