iOS之property裡的copy、strong區別

weixin_34402408發表於2016-11-19

Objective-C中mutableCopy和copy的理解講述了深拷貝和淺拷貝,就容易理解property裡的copy、strong了

#import <Foundation/Foundation.h>

@interface ZJPerson : NSObject

@property (nonatomic,copy) NSString * name;

@property (nonatomic,strong) NSString * StrongName;

@end

測試如下:

NSMutableString * name = [NSMutableString stringWithFormat:@"iOS俱哥"];

ZJPerson * p = [[ZJPerson alloc]init];
p.name = name;
p.StrongName = name;
// 不能改變p.name的值,因為其內部copy新的物件
//改變了p.StrongName的值,因為StrongName和name指向了同一塊記憶體
[name appendString:@"!!!"];

NSLog(@"p.name = %@",p.name);
NSLog(@"p.StrongName = %@",p.StrongName);

NSLog(@"name:%p,p.name:%p,p.StrongName:%p",name,p.name,p.StrongName);

注:在strong情況下,如果外部被引用的變數更改了,那裡面這個值也會更改,因為兩個屬性指向同一塊記憶體空間 。在這裡strong 屬於淺拷貝,只賦值物件的指標。
為了防止外界修改name,就用copy,因為copy是生成了一份新的記憶體空間,,所以外界是不能修改值。

2362273-cc73b9dd4de0207a.png

在這裡給出一道常見面試題,看了上述的講解,這道題就能很好地理解了:

用@property宣告的NSString(或NSArray,NSDictionary)經常使用copy關鍵字,為什麼?如果改用strong關鍵字,可能造成什麼問題?

答:用@property宣告 NSString、NSArray、NSDictionary 經常使用copy關鍵字,是因為他們有對應的可變型別:NSMutableString、NSMutableArray、NSMutableDictionary,他們之間可能進行賦值操作,為確保物件中的字串值不會無意間變動,應該在設定新屬性值時拷貝一份。
如果我們使用是strong,那麼這個屬性就有可能指向一個可變物件,如果這個可變物件在外部被修改了,那麼會影響該屬性。
copy此特質所表達的所屬關係與strong類似。然而設定方法並不保留新值,而是將其“拷貝” (copy)。 當屬性型別為NSString時,經常用此特質來保護其封裝性,因為傳遞給設定方法的新值有可能指向一個NSMutableString類的例項。這個類是NSString的子類,表示一種可修改其值的字串,此時若是不拷貝字串,那麼設定完屬性之後,字串的值就可能會在物件不知情的情況下遭人更改。所以,這時就要拷貝一份“不可變” (immutable)的字串,確保物件中的字串值不會無意間變動。只要實現屬性所用的物件是“可變的” (mutable),就應該在設定新屬性值時拷貝一份。

END

相關文章