copy和mutableCopy
来源:互联网 发布:淘宝客qq群推广违规吗 编辑:程序博客网 时间:2024/05/09 11:37
一、copy和mutableCopy
NSObject类有两个跟拷贝相关的方法:copy和mutableCopy。这两个方法都是返回一个id类型的对象。
- ①、copy方法:返回copyWithZone方法返回的对象(Returns the object returned by copyWithZone:);
- ②、mutableCopy方法:返回mutableCopyWithZone方法返回的对象(Returns the object returned by mutableCopyWithZone:);
二、NSString对象调用copy和mutableCopy
- 1、先定义如下通用宏:
//打印方法名#define LOG_METHOD_NAME {NSLog(@"%@", NSStringFromSelector(_cmd));}//打印对象的类名,以及对象本身的地址#define LOG_OBJ_ADDRESS(obj) {NSLog(@"%@ : %p",NSStringFromClass([obj class]), obj);}//打印空行#define LOG_END {NSLog(@"%@", @" ");}
- 2、测试代码如下:
- (void)stringCopyTest{ LOG_METHOD_NAME NSString *str = @"Hello"; LOG_OBJ_ADDRESS(str); NSString *cpStr = [str copy]; LOG_OBJ_ADDRESS(cpStr); NSMutableString *mutCpStr = [str mutableCopy]; LOG_OBJ_ADDRESS(mutCpStr); LOG_END}
3、打印如下:
2015-12-22 15:14:33.416 toast显示[53390:2099784] stringCopyTest2015-12-22 15:14:33.416 toast显示[53390:2099784] __NSCFConstantString : 0x10aed26b02015-12-22 15:14:33.416 toast显示[53390:2099784] __NSCFConstantString : 0x10aed26b02015-12-22 15:14:33.416 toast显示[53390:2099784] __NSCFString : 0x7fe071c1ee402015-12-22 15:14:33.416 toast显示[53390:2099784]
4、总结
由以上输出可知,对一个NSString对象调用copy返回的还是该对象本身,因为str的地址和cpStr的地址是用一个。而调用mutableCopy,返回的是一个NSMutableString对象。注:__NSCFConstantString是常量串即NSString,而__NSCFString是可变串即NSMutableString
二、NSMutableString对象调用copy和mutableCopy
- 1、测试代码如下:
- (void)mutableStringCopyTest{ LOG_METHOD_NAME NSMutableString *mutStr = [@"OC" mutableCopy]; LOG_OBJ_ADDRESS(mutStr); NSMutableString *cpMutStr = [mutStr copy]; LOG_OBJ_ADDRESS(cpMutStr); NSMutableString *mutCpMutStr = [mutStr mutableCopy]; LOG_OBJ_ADDRESS(mutCpMutStr); LOG_END}
2、打印如下:
2015-12-22 15:20:06.162 toast显示[53437:2103898] mutableStringCopyTest2015-12-22 15:20:06.163 toast显示[53437:2103898] __NSCFString : 0x7fe4b1d133f02015-12-22 15:20:06.163 toast显示[53437:2103898] NSTaggedPointerString : 0xa0000000000434f22015-12-22 15:20:06.163 toast显示[53437:2103898] __NSCFString : 0x7fe4b1c033a02015-12-22 15:20:06.163 toast显示[53437:2103898]
3、总结
由以上输出可知,对一个NSMutableString对象调用copy返回的是一个NSTaggedPointerString对象,该对象可认为是一个常量串。而调用mutableCopy返回的是另外一个可变对象__NSCFString,即NSMutableString(原NSMutableString对象的地址是0x7fe4b1d133f0,新NSMutableString的对象地址是0x7fe4b1c033a0)。PS:针对NSArray、NSDictionary、NSSet等具有Mutable版本的类进行实验出现跟NSString类似的现象;
三、copy和mutableCopy调用小结
针对不可变对象调用copy返回该对象本身,调用mutableCopy返回一个可变对象(新的);
针对可变对象调用copy返回一个不可变对象(新的),调用mutableCopy返回另外一个可变对象(新的)。
四、属性copy还是strong
- 1、假设定义两个id类型如下
@property (nonatomic, copy) id cpID;@property (nonatomic, strong) id stID;
- 2、那么编译器把以上两属性分别实现为:
@synthesize cpID = _cpID;@synthesize stID = _stID;- (void)setCpID:(id)cpID{ _cpID = [cpID copy];}- (id)cpID{ return _cpID;}- (void)setStID:(id)stID{ _stID = stID;}- (id)stID{ return _stID;}
3、结论:
从以上实现可以看出,strong和copy的属性主要是set方法有区别,strong的set是直接设置指定值,而copy的set是设置指定值的copy版本。
五、NSString的属性是copy还是strong
- 1、测试代码如下:
@interface ViewController ()@property (nonatomic, copy) NSString *cpStr;@property (nonatomic, strong) NSString *stStr;@end@implementation ViewController- (void)stringPropertyTest{ LOG_METHOD_NAME; NSMutableString* mutStr = [@"123" mutableCopy]; LOG_OBJ_ADDRESS(mutStr); self.cpStr = mutStr; LOG_OBJ_ADDRESS(self.cpStr); self.stStr = mutStr; LOG_OBJ_ADDRESS(self.stStr); NSLog(@"修改前"); NSLog(@"mutStr:%@", mutStr); NSLog(@"copy:%@", self.cpStr); NSLog(@"strong:%@", self.stStr); [mutStr appendString:@"456"]; NSLog(@"修改后"); NSLog(@"mutStr:%@", mutStr); NSLog(@"copy:%@", self.cpStr); NSLog(@"strong:%@", self.stStr); LOG_END}
2、打印结果如下:
2015-12-29 00:13:13.630 toast显示[10615:514242] stringPropertyTest2015-12-29 00:13:13.630 toast显示[10615:514242] __NSCFString : 0x7fd63851f6a02015-12-29 00:13:13.630 toast显示[10615:514242] NSTaggedPointerString : 0xa0000000033323132015-12-29 00:13:13.630 toast显示[10615:514242] __NSCFString : 0x7fd63851f6a02015-12-29 00:13:13.630 toast显示[10615:514242] 修改前2015-12-29 00:13:13.630 toast显示[10615:514242] mutStr:1232015-12-29 00:13:13.630 toast显示[10615:514242] copy:1232015-12-29 00:13:13.631 toast显示[10615:514242] strong:1232015-12-29 00:13:13.631 toast显示[10615:514242] 修改后2015-12-29 00:13:13.631 toast显示[10615:514242] mutStr:1234562015-12-29 00:13:13.631 toast显示[10615:514242] copy:1232015-12-29 00:13:13.632 toast显示[10615:514242] strong:1234562015-12-29 00:13:13.632 toast显示[10615:514242]
3、结论:
由以上输出可知,假设两个NSString属性实际上指向的都是一个NSMutableString对象,那么在原NSMutableString对象修改后,strong版本的NSString属相跟着修改,而copy版本属性保持原状。self.cpStr实际上是一个NSTaggedPointerString对象,该对象正是NSMutableString对象执行copy的返回值;
六、NSMutableString的属性是copy还是strong
- 1、测试代码如下:
@interface ViewController ()@property (nonatomic, copy) NSMutableString *cpMutStr;@property (nonatomic, strong) NSMutableString *stMutStr;@end@implementation ViewController- (void)stringPropertyTest{ LOG_METHOD_NAME; NSMutableString* mutStr = [@"123" mutableCopy]; LOG_OBJ_ADDRESS(mutStr); self.cpMutStr = mutStr; LOG_OBJ_ADDRESS(self.cpMutStr); self.stMutStr = mutStr; LOG_OBJ_ADDRESS(self.stMutStr); NSLog(@"修改前"); NSLog(@"mutStr:%@", mutStr); NSLog(@"copy:%@", self.cpMutStr); NSLog(@"strong:%@", self.stMutStr); [mutStr appendString:@"456"]; NSLog(@"修改后"); NSLog(@"mutStr:%@", mutStr); NSLog(@"copy:%@", self.cpMutStr); NSLog(@"strong:%@", self.stMutStr); LOG_END [self.cpMutStr appendString:@"789"];}
2、打印结果如下:
2015-12-29 00:31:24.807 toast显示[570:9278] stringPropertyTest2015-12-29 00:31:24.807 toast显示[570:9278] __NSCFString : 0x7fec70c20c602015-12-29 00:31:24.807 toast显示[570:9278] __NSCFString : 0x7fec70c3e9502015-12-29 00:31:24.807 toast显示[570:9278] __NSCFString : 0x7fec70c20c602015-12-29 00:31:24.807 toast显示[570:9278] 修改前2015-12-29 00:31:24.807 toast显示[570:9278] mutStr:1232015-12-29 00:31:24.808 toast显示[570:9278] copy:1232015-12-29 00:31:24.808 toast显示[570:9278] strong:1232015-12-29 00:31:24.808 toast显示[570:9278] 修改后2015-12-29 00:31:24.808 toast显示[570:9278] mutStr:1234562015-12-29 00:31:24.808 toast显示[570:9278] copy:1232015-12-29 00:31:24.808 toast显示[570:9278] strong:1234562015-12-29 00:31:24.808 toast显示[570:9278]
3、结论:
看起来没啥问题,strong版本的属性跟随原对象的变化而变化,copy版本的属性不变。但是,假设调用[self.cpMutStr appendString:@"789"];
程序会崩溃。崩溃信息如下:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa000000003332313'*** First throw call stack:
原因很明显,是朝NSTaggedPointerString对象发了一个它不能识别的selector。原因是copy版本的NSMutableString属性本质上不是一个NSMutableString对象,而是一个NSTaggedPointerString对象,它是一个不可变对象。该对象是NSMutableString对象执行copy得来的,还记得我们上一节的结论吗?对一个对象执行copy得到的用于是一个不可变的对象。
PS:针对NSArray、NSDictionary、NSSet等具有Mutable版本的类进行试验出现跟NSString类似的现象。
本文来至从copy和mutableCopy谈起
- copy和mutableCopy
- iphone copy 和mutablecopy
- copy和mutablecopy浅见
- copy和mutablecopy
- copy和mutablecopy
- copy和mutablecopy
- copy和mutableCopy
- Copy和MutableCopy
- copy和mutableCopy
- copy和mutableCopy
- copy和MutableCopy
- copy和mutableCopy
- copy和mutableCopy
- Copy和MutableCopy
- copy和mutableCopy,retain
- copy 和 mutableCopy
- copy和mutablecopy
- Copy和MutableCopy
- Java 内存分配全面浅析
- Codeforces Round #337 (Div. 2) 战报
- Codeforces Round #337 (Div. 2) 610B Vika and Squares(脑洞)
- iOS uilabel自动换行
- 数据结构C语言利用堆栈表达式求值
- copy和mutableCopy
- 零崎的补番计划Ⅱ(0-1背包问题)
- APP字体大小,不随系统的字体大小变化而变化的方法
- hadoop 之eclipse插件定做
- Java 多线程:多线程产生的原因
- Codeforces Round #337 (Div. 2) 610C Harmony Analysis(脑洞)
- 回调机制
- 世界是数字的(一)
- index