關於iOS開發中copy的使用

weixin_33762321發表於2018-05-23

在iOS開發中我們在使用@property定義屬性的時候經常會使用copy屬性來個對一個NSString或者NSArray、NSDictionary來進行修飾,然而許多同學只是在別人的程式碼上看到,學習這樣使用。
也有一部分同學是大概瞭解一點,主要是為了讓該物件持有賦值物件的副本,避免被賦值物件在其他地方被修改,造成錯誤(我也是屬於這一類。。),該文章主要是為了提升自己對copy屬性的理解,並且區分什麼時候使用才正確。

1.為什麼要使用copy?

  • 因為父類指標可以指向子類物件,使用copy修飾物件的話,無論賦值物件是可變還是不可變的,物件本身持有的都是一個不可變的副本,這樣就避免外界的影響。(其實這一個話是有點問題的,用copy修飾的物件如果傳入一個不可變物件,其實也只是單純的指標拷貝,指向的還是同一塊記憶體,但是個人水平有限,對於記憶體問題不敢妄下定論)
  • 如果我們使用strong修飾物件的話,該物件可能會指向一個可變物件,如果這個可變物件發生改變的話,使用strong修飾的物件也會受到影響。

我們在日常使用NSString的時候,為了避免物件在某個地方被改變,而開發者也無法發現這種情況出現,我們經常都是使用copy修飾物件,這個時候即使傳入一個“可變”物件,這個時候我們這個NSString 物件持有的只是該“可變”物件的一個“不可變”的副本。

2.在那些地方使用copy

首先這裡要區分淺拷貝和深拷貝、集合物件和非集合物件

淺拷貝:一般理解為指標拷貝,就是會拷貝一個新的指標,但是指標指向的記憶體地址依然保持不變

深拷貝: 可以理解為內容拷貝,也就是說不僅會拷貝一份指標,同時對內容也會進行一次拷貝,相當於複製了一個副本

下面開始區分什麼時候回進行淺拷貝,什麼時候會進行深拷貝(按照集合型別和非集合型別討論)

  • 對於非集合物件:
操作 結果
[不可變物件 copy] 淺拷貝
[不可變物件 mutableCopy] 深拷貝
[可變物件 copy] 深拷貝
[可變物件 mutableCopy] 深拷貝

就是說我們一般使用copy修飾一個NSString的時候,傳入另外一個NSString的時候,只會複製一份新的指標,指向的還是同一個地址。但是由於傳入的NSString是一個不可變物件,我們也不用擔心它在其它地方被隨意更改了。

@property(nonatomic,strong)NSString *strongString;

NSMutableString *mutString = [NSMutableString stringWithString:@"milan"];

self.strongString = [mutString copy];

類似以上操作,用Strong修飾的NSString物件所持有的也是一個"不可變"的副本

  • 對於集合型別物件:
操作 結果
[不可變物件 copy] 淺拷貝
[不可變物件 mutableCopy] 深拷貝
[可變物件 copy] 深拷貝
[可變物件 mutableCopy] 深拷貝

注意!對於集合型別的物件,內容拷貝的只有物件本身,對於集合型別內部的元素只進行淺拷貝,就是隻拷貝指標

對於在什麼地方使用Copy修飾物件,沒有硬性要求,理解copy 以及mutableCopy以後,在何處使用自行判斷就可以,當然為了避免自己很多時候考慮不周,我們一般建議使用copy修飾例項變數

3.使用copy的注意點

@property (nonatomic,copy)NSMutableArray *mutArray;

NSMutableArray *testArray = [NSMutableArray arrayWithObject:@"milan"];

self.mutArray = [testArray copy];

對於以上的操作在一般使用上是沒有問題的,但是當你的mutArray想要插入或刪除內容的時候會報錯,因為[testArray copy]賦值給mutArray以後,其實它持有的是一個“不可變”的副本,即使你本身定義為一個可變物件。

最後

以上內容是參考別人的東西並加上自己的理解得出的,若有錯誤之處請指出,並且對於使用copy需要注意的地方,希望有更多的發現

相關文章