天天看點

Objective - C 一一 NSString什麼時候用copy,什麼時候用strong

我們在聲明一個NSString屬性時,對于其記憶體相關特性,通常有兩種選擇(基于ARC環境):strong與copy。那這兩者有什麼差別呢?什麼時候該用strong,什麼時候該用copy呢?

首先舉個例子:

這裡有一個person類,有一個使用cooy的NSString屬性.

毋庸置疑的是,字元串屬性使用copy,當外界修改了字元串,裡面不會改變.

在ViewController.m檔案中

注意: 此時的NSString屬性name是使用copy的.

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 不可變字元串
    NSString *nameStr = @"zy";
    
    Person *person = [[Person alloc] init];
    
    person.name = nameStr;
    
    NSLog(@"%p ---- %p",nameStr,person.name);
    
    
}
           

輸出結果:

因為NSString是不可變字元串,當使用copy的時候,不會生成一個新的對象,因為源對象是不可更改的對象,那麼拷貝出來的也是不可更改的對象,兩者互不影響.是以不會産生新的對象.

當把NSString的屬性改為strong,此時仍使用NSString不可變字元串.列印結果如下:

2017-08-31 18:23:36.487 NSSting_copy_strong[4747:199526] 0x103e44068 ---- 0x103e44068

           

是以,在不可變字元串的情況下,無論使用strong,還是copy.其位址指向的都是同一塊存儲空間.

注意: 當把.m檔案中的NSString不可變字元串改為可變字元串之後.

此時NSString的屬性使用的strong.

- (void)viewDidLoad {
    [super viewDidLoad];
    
    // 可變字元串
    NSMutableString *nameStr = [NSMutableString stringWithFormat:@"zy"];
    
    Person *person = [[Person alloc] init];
    
    person.name = nameStr;
    
    NSLog(@"%p ---- %p",nameStr,person.name);
    
    
}
           

輸出結果:

而把NSString的屬性改為copy後.

輸出結果:

此時copy屬性的字元串已經不再指向nameStr的記憶體位址了.而是深拷貝了一份記憶體位址,并讓 _name屬性指向這塊記憶體位址.

當源字元串是NSString的時候,無論使用strong,copy屬性的對象,都會指向源對象,此時copy隻是做了一次淺拷貝.

當源字元串是NSSMutableString的時候,copy屬性對源字元串做了一次深拷貝,建立了一個新的對象,并指向新對象的記憶體位址.

注意: 

一般情況下我們在開發中使用的大多數都是NSString不可變字元串.在網絡中加載的資料大多也是不可變的.當使用不可變字元的時候,strong,copy都不會産生新的對象.這個時候建議使用strong;原因如下:

當NSString屬性使用copy的時候.

此時name的set方法是這樣的.

// copy情況下的屬性name的set方法
- (void)setName:(NSString *)name
{
    _name = [name copy];
}
           

在set方法中,每次都會去判斷name是NSString的還是NSMutableString的.如果是NSString不可變字元串的時候,就不會去生成新的對象,如果是可變字元串,就會去生成新的對象.這樣會進行一次判斷操作.

當NSString屬性使用strong的時候

此時name的set方法是這樣的

// strong情況下的屬性name的set方法
- (void)setName:(NSString *)name
{
    _name = name;
}
           

在set方法中不用去判斷,外界傳入的可變或不可變字元.這樣提高了性能.是以當外界傳入的字元串是NSString不可變字元串的時候,建議使用strong.

關于本章内容比較好的博文: http://www.cocoachina.com/ios/20150512/11805.html