iOS copy mutableCopy詳解
一、從面向物件到Objective-C概覽copy
1、面向物件:
In object-oriented programming, object copying is creating a copy of an existing object, a unit of data in object-oriented programming. The resulting object is called an object copy or simply copy of the original object. Copying is basic but has subtleties and can have significant overhead. There are several ways to copy an object, most commonly by a copy constructor or cloning. Copying is done mostly so the copy can be modified or moved, or the current value preserved. If either of these is unneeded, a reference to the original data is sufficient and more efficient, as no copying occurs.
在面向物件的程式設計中,物件的copy就是建立一個已經存在的物件的copy。這種物件的建立的結果被稱為原始物件的copy。copy是很基礎的,但是也有其精巧的地方,並且可能造成巨大的消耗。有很多種方式可以copy物件,最常用的就是copy構造器和克隆。copy經常用於物件的修改、移動和保護。如果上述的幾種應用都不需要,持有原始物件的引用就足夠了,並不需要copy。
2、OC:
In Objective-C, the methods copy and mutableCopy are inherited by all objects and intended for performing copies; the latter is for creating a mutable type of the original object. These methods in turn call the copyWithZone and mutableCopyWithZone methods, respectively, to perform the copying. An object must implement the corresponding copyWithZone method to be copyable.
在OC中,copy和mutableCopy兩個方法是被所有物件繼承的(有點小毛病,應該指所有繼承自NSObject的類),這兩個方法就是為copy準備的。其中,mutableCopy是為了建立原始物件的可變型別的copy。這兩個方法分別呼叫copyWithZone和mutableCopyWithZone兩個方法來進行copy。一個物件必須實現copyWithZone或者mutableCopyWithZone,才能進行copy或者mutableCopy。
那麼,我們可以從以上獲取到什麼資訊?
-
copy經常用於物件的修改、移動和保護。如果上述的幾種應用都不需要,持有原始物件的引用就足夠了,並不需要copy。
-
一個類必須實現copyWithZone或者mutableCopyWithZone,才能進行copy或者mutableCopy。
下一階段,本文將展開講述OC中的copy相關資訊以及如何使用copy方法。
二、Objective-C中copy相關
1、OC中的copy相關內容
-
在XCode 裡Foundation.framework下的Headers裡,也在系統裡找到原檔案:/System/Library/Frameworks/Foundation.framework/Versions/C/Headers/NSObject.h
1 2 3 4 5 6 |
@protocol NSCopying
- (id)copyWithZone:(nullable NSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullable NSZone *)zone;
@end
|
-
在/usr/include/objc 下面找到 runtime 的 NSObject.h
1 2 |
- (id)copy;
- (id)mutableCopy;
|
-
修飾屬性的關鍵字copy
2、這裡需要注意的有以下幾點
-
若想使用copy和mutableCopy,需要分別實現NSCopying協議和NSMutableCopying協議,即實現copyWithZone:和mutableCopyWithZone:方法。
-
繼承自NSObject的大部分框架類均預設實現了NSCopying,並且一些具備可變型別的類如NSString、NSArray、NSDictionary,以及它們的可變型別類NSMutableString、NSMutableArray和NSMutableDictionary也實現了NSMutableCopying。(查了大部分常用類,均實現了NSCopying,所以暫時這麼說吧,可能有人說NSNumber並沒有實現NSCopying,那你可以看一下它的父類NSValue,其實現了NSCopying)
-
對於一些自定義類,需要自己實現NSCopying。具體方式且看下部分。
三、非容器物件的深淺copy
首先,我們談一下非容器物件的深淺copy,這些非容器物件,包含常用的NSString、NSNumber等,也包括我們自定義的一些非容器類的例項。下面分三個三面進行分析。
1、首先說說深淺copy
準則
淺copy:指標複製,不會建立一個新的物件。
深copy:內容複製,會建立一個新的物件。
此處,不進行過多的解釋,從下面的結果分析中,按例子來理解。
2、框架類的深淺copy
準則
探究框架類深copy還是淺copy,需要清楚的是該類如何實現的NSCopying和NSMutableCopy的兩個方法copyWithZone:和mutableCopyWithZone:。然而OC並不開源,並且本文這裡也不會進行原始碼的推測。
那麼,我們應該遵循怎樣一個原則呢?如下:
-
對immutableObject,即不可變物件,執行copy,會得到不可變物件,並且是淺copy。
-
對immutableObject,即不可變物件,執行mutableCopy,會得到可變物件,並且是深copy。
-
對mutableObject,即可變物件,執行copy,會得到不可變物件,並且是深copy。
-
對mutableObject,即可變物件,執行mutableCopy,會得到可變物件,並且是深copy。
程式碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// 此處以NSString為例探究框架類深淺copy
// 不可變物件
NSString *str = @ "1" ;
NSString *str1 = [str copy];
NSString *str2 = [str mutableCopy];
// 可變物件
NSMutableString *mutableStr = [NSMutableString stringWithString:@ "1" ];
NSMutableString *mutableStr1 = [mutableStr copy];
|