結(jié)論
- 對于copy修飾的屬性來說,若賦值源是NSString、NSArray互纯、NSURLRequest三者其中之一晒杈,復(fù)制時是shallow copy(淺復(fù)制)系馆,即地址相同,類型相同。
- 一般情況下,NSString使用copy修飾基显。即:
@property (nonatomic, copy) NSString *string;
解釋說明
結(jié)論1
首先,需要知道
copy和strong對應(yīng)的所有權(quán)修飾符都是 __strong善炫。
strong修飾的屬性撩幽,賦值后,地址相同箩艺,類型相同窜醉。
copy修飾的屬性,賦值時舅桩,通過 NSCopying 接口的 copyWithZone: 方法復(fù)制賦值源所生成的對象酱虎,賦值后,地址不一定相同擂涛,類型不一定相同。
而復(fù)制分為shallow copy與deep copy聊记,區(qū)別如下:
shallow copy 即淺復(fù)制撒妈,沒有產(chǎn)生新對象,指針指向原來對象排监。
deep copy 即深復(fù)制狰右,產(chǎn)生新對象。
接著舆床,Show the code
String相關(guān)屬性
@property (nonatomic, strong) NSString *strongString; /**<strong string*/
@property (nonatomic, strong) NSMutableString *mStrongString; /**<strong mutable string*/
@property (nonatomic, copy) NSString *cString; /**<copy string*/
@property (nonatomic, copy) NSMutableString *mCopyString; /**<copy mutable string*/
對String的測試
- (void)stringTest {
//來源是NSString
NSString *string = @"string";
NSLog(@"address: %p | class: %@ of string",string,[string class]);
self.strongString = string;
self.cString = string;
self.mStrongString = string;
self.mCopyString = string;
[self printStringInfo];
NSLog(@"\n");
//來源是NSMutableString
NSMutableString *mutableString = [NSMutableString stringWithString:@"mutable string"];
NSLog(@"address: %p | class: %@ of mutable string",mutableString,[mutableString class]);
self.strongString = mutableString;
self.cString = mutableString;
self.mStrongString = mutableString;
self.mCopyString = mutableString;
[self printStringInfo];
}
- (void)printStringInfo {
NSLog(@"address: %p | class: %@ of strong string",self.strongString,[self.strongString class]);
NSLog(@"address: %p | class: %@ of copy string",self.cString,[self.cString class]);
NSLog(@"address: %p | class: %@ of strong mutable string",self.mStrongString,[self.mStrongString class]);
NSLog(@"address: %p | class: %@ of copy mutable string",self.mCopyString,[self.mCopyString class]);
}
(注:以上是只有部分代碼棋蚌,想了解更多嫁佳,請查看文章底部的源代碼)
然后,分別打印來源是NSString谷暮、NSArray蒿往、NSURLRequest的運(yùn)行結(jié)果:
對比以上3張圖中的地址及類型,可知:
來源是NSString湿弦、NSArray瓤漏、NSURLRequest三者之一的,使用strong或copy修飾的颊埃,賦值結(jié)果都是一樣的蔬充,可證明結(jié)論1:
對于copy修飾的屬性來說,若賦值源是NSString班利、NSArray饥漫、NSURLRequest三者其中之一,復(fù)制時是shadow copy(淺復(fù)制)罗标,即地址相同庸队,類型相同。
結(jié)論2
分別打印來源是NSMutableString馒稍、NSMutableArray皿哨、NSMutableNSURLRequest的結(jié)果:
對比以上3張圖中的地址及類型,可知:
來源若是NSMutableString纽谒,NSMutableArray证膨,NSMutableURLRequest之一
- 使用strong修飾的,賦值后鼓黔,地址相同央勒,類型也相同。
- 使用copy修飾的澳化,會復(fù)制賦值源所生成的對象崔步,復(fù)制后,地址不同缎谷,而來源是NSMutableArray的井濒,甚至連類型也不同(
__NSArrayI
與__NSArrayM
),說明復(fù)制時都是deep copy(深復(fù)制)列林。
(據(jù)了解瑞你,copy除了復(fù)制NSString、NSArray希痴、NSURLRequest外者甲,其他都是deep copy。)(未知真實性)
也就是說:
如果來源是NSString砌创,使用copy或strong沒有區(qū)別虏缸。
如果來源是NSMutableString鲫懒,NSString對象會因其改變而改變。若使用copy
刽辙,因為是深復(fù)制窥岩,產(chǎn)生了一個新的對象,就可以避免以上情況扫倡。
而一般使用NSString變量時谦秧,并不希望它可變,Objective-C的類型確定又是在運(yùn)行時才決定的撵溃,那么賦值時疚鲤,很可能會搞錯賦值源的類型:NSMutableString誤當(dāng)作NSString,這樣也許會帶來不可預(yù)知的問題缘挑,而且此類問題一般不易察覺集歇,所以可說明結(jié)論2:
一般情況下,NSString使用copy修飾语淘。
當(dāng)然诲宇,具體情況,具體分析惶翻,使用strong也無可厚非姑蓝。
附錄:剩余的主要代碼
Array相關(guān)屬性
@property (nonatomic, strong) NSArray *strongArray; /**<strong array*/
@property (nonatomic, strong) NSMutableArray *mStrongArray; /**<strong mutable array*/
@property (nonatomic, copy) NSArray *cArray; /**<copy array*/
@property (nonatomic, copy) NSMutableArray *mCopyArray; /**<copy mutable array*/
URL Request相關(guān)屬性
@property (nonatomic, strong) NSURLRequest *strongRequest; /**<strong request*/
@property (nonatomic, strong) NSMutableURLRequest *mStrongRequest; /**<strong mutalbe request*/
@property (nonatomic, copy) NSURLRequest *cRequest; /**<copy request*/
@property (nonatomic, copy) NSMutableURLRequest *mCopyRequest; /**<copy mutable request*/
對Array的測試
- (void)arrayTest {
//來源是NSArray
NSArray *array = @[ @"item1",@"item2"];
NSLog(@"address: %p | class: %@ of array",array,[array class]);
self.strongArray = array;
self.cArray = array;
self.mStrongArray = array;
self.mCopyArray = array;
[self printArrayInfo];
NSLog(@"\n");
//來源是NSMutableArray
NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:array];
NSLog(@"address: %p | class: %@ of mutable array",mutableArray,[mutableArray class]);
self.strongArray = mutableArray;
self.cArray = mutableArray;
self.mStrongArray = mutableArray;
self.mCopyArray = mutableArray;
[self printArrayInfo];
}
- (void)printArrayInfo {
NSLog(@"address: %p | class: %@ of strong array",self.strongArray,[self.strongArray class]);
NSLog(@"address: %p | class: %@ of copy array",self.cArray,[self.cArray class]);
NSLog(@"address: %p | class: %@ of strong mutable array",self.mStrongArray,[self.mStrongArray class]);
NSLog(@"address: %p | class: %@ of copy mutable array",self.mCopyArray,[self.mCopyArray class]);
}
對URL Request的測試
- (void)urlRequestTest {
//來源是NSURLRequest
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSLog(@"address: %p | class: %@ of url request",urlRequest,[urlRequest class]);
self.strongRequest = urlRequest;
self.cRequest = urlRequest;
self.mStrongRequest = urlRequest;
self.mCopyRequest = urlRequest;
[self printRequestInfo];
NSLog(@"\n");
//來源是NSMutableURLRequest
NSMutableURLRequest *mutableURLRequest = [NSMutableURLRequest requestWithURL:url];
NSLog(@"address: %p | class: %@ of mutable request",mutableURLRequest,[mutableURLRequest class]);
self.strongRequest = mutableURLRequest;
self.cRequest = mutableURLRequest;
self.mStrongRequest = mutableURLRequest;
self.mCopyRequest = mutableURLRequest;
[self printRequestInfo];
}
- (void)printRequestInfo {
NSLog(@"address: %p | class: %@ of strong request",self.strongRequest,[self.strongRequest class]);
NSLog(@"address: %p | class: %@ of copy request",self.cRequest,[self.cRequest class]);
NSLog(@"address: %p | class: %@ of strong mutable equest",self.mStrongRequest,[self.mStrongRequest class]);
NSLog(@"address: %p | class: %@ of copy mutable request",self.mCopyRequest,[self.mCopyRequest class]);
}