1. 程式人生 > >NSstring為什麼使用copy copy的深度解析

NSstring為什麼使用copy copy的深度解析

面試中經常問到的一個題,如果只是答到copy就是會單獨複製一份,重新開闢一個地址空間。不會因為原值的修改而修改。這樣回答100分只是拿到了10分。面試官會進一步追問。直到問到你不會。。。

入門的回答以後,遞進問題。

1.那你跟我說一下copy 還有strong的區別

上程式碼

@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
    NSMutableString *string = [NSMutableString stringWithFormat:@"aaa"];
    self.strongString = string;
    self.copyedString = string;
    //string = [NSMutableString stringWithFormat:@"aaa"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];
    [string appendString:@"bbb"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];

看一下輸出結果:



可以看到,strong string的指向記憶體地址和string是一樣的。但是copy string是不一樣的,也就是說copy但開闢了記憶體地址。從輸出結果看,copy string並沒有因為string的內容修改而改變。但是strong就被改變了。因為strong是指標拷貝(引用計數拷貝)。而copy是內容拷貝(深拷貝)

2.那什麼情況下copy 和 strong修飾,效果是一樣的。

上程式碼:

    NSString *string = [NSString stringWithFormat:@"aaa"];
    self.strongString = string;
    self.copyedString = string;
    //string = [NSMutableString stringWithFormat:@"aaa"];
    NSLog(@"origin string: %p, %p", string, &string);
    NSLog(@"strong string: %p, %p", _strongString, &_strongString);
    NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
    self.outputLabel.text = [NSString stringWithFormat:@"origin string:%@\n,strong string:%@\n,copy string %@",string,_strongString,_copyedString];

                         

可以看到 如果是不可變拷貝不可變的副本,是不會重新開闢空間。輸出就可以看到。3塊輸出的記憶體地址是一樣的。這同樣適用於陣列。

3.那如果是自定義類,你怎麼讓它具有copy功能。能大概跟我說一下ios是如何處理的

答:遵守NScoping協議,實現copywithzone方法。大致流程如下圖


4.block為什麼使用copy

block使用copy是在MRC中延續下來的,在MRC下,方法內部的block是存放在棧區,使用copy會將block拷貝到堆區。
在ARC下編譯器會自動對block進行copy,因此我們使用copy或者strong的效果是一樣的。但是我們在ARC下繼續使用copy可以提醒我們編譯器會自動幫我們實現copy的操作。

typedef void (^AlertBlock)();
@interface AwardView : UIView
@property (nonatomic,copy) AlertBlock closeBlock;
@end