@whiteiOS
2017-03-27T08:45:21.000000Z
字数 3197
阅读 622
iOS学习之路
- (id)copyWithZone:(NSZone *)zone;,我们就是通过这个方法给对象提供拷贝的功能
copy得到的总是不可变对象,不管之前是可变还是不可变;mutableCopy得到的总是可变对象,不管之前是可变还是不可变
NSString *string = @"123456";//没有产生新对象NSString *copyString = [string copy];//产生新对象NSString *mutableString = [string mutableCopy];NSLog(@"string=%p copyString=%p mutableString=%p", string, copyString, mutableString);
打印结果:
string=0x1024b5068 copyString=0x1024b5068 mutableString=0x600000262980
小结:对NSString对象进行copy只是浅拷贝,并不会产生新的对象;对NSString对象进行mutableCopy是深拷贝,会产生新的对象
NSMutableString *string = [NSMutableString stringWithFormat:@"123456"];//产生新对象NSString *copyString = [string copy];//产生新对象NSMutableString *mutableString = [string mutableCopy];NSLog(@"string=%p copyString=%p mutableString=%p", string, copyString, mutableString);
打印结果:
string=0x60800007ce40 copyString=0xa003635343332316 mutableString=0x60800007d080
小结:对NSMutableString对象进行copy和mutableCopy都是深拷贝,都会产生新的对象
总结:对于不可变对象的copy是浅拷贝,mutableCopy是深拷贝;对于可变对象的copy和mutableCopy都是深拷贝
@interface Person : NSObject <NSCopying>@property (nonatomic, copy) NSString *name;@property (nonatomic, assign) int age;@end
- (id)copyWithZone:(NSZone *)zone方法而直接拷贝的话,程序就会崩溃,报错如下:
reason: '-[Person copyWithZone:]: unrecognized selector sent to instance 0x608000024f80'
- (id)copyWithZone:(NSZone *)zone方法
- (id)copyWithZone:(NSZone *)zone{Person *p = [[Person allocWithZone:zone] init];return p;}
- (void)test1{Person *p = [[Person alloc] init];p.name = @"jack";p.age = 18;Person *copyP = [p copy];//产生了新对象,深拷贝NSLog(@"p=%p copyP=%p", p, copyP);NSLog(@"name=%@ age=%d", copyP.name, copyP.age);}
- (id)copyWithZone:(NSZone *)zone{Person *p = [[Person allocWithZone:zone] init];p.name = self.name;p.age = self.age;return p;}
小结:当自定义对象调用copy时,会产生新对象,属于深拷贝
@interface Person : NSObject@property (nonatomic, copy) NSString *name;@end
NSMutableString *string = [NSMutableString stringWithFormat:@"jack"];Person *p = [[Person alloc] init];p.name = string;[string appendString:@"123"];NSLog(@"%@", p.name);
打印结果为:jack
当使用copy修饰属性的时候,属性的setter方法会调用copy产生新的对象,这样,当原对象的值发生改变时,并不影响新对象的值
@property (nonatomic, copy) NSString *name;//当调用上面的copy的时候,等价于下面的代码- (void)setName:(NSString *)name{if (_name != name) {[_name release];_name = [name copy];}}
@interface Person : NSObject@property (nonatomic, strong) NSString *name;@end
NSMutableString *string = [NSMutableString stringWithFormat:@"jack"];Person *p = [[Person alloc] init];p.name = string;[string appendString:@"123"];NSLog(@"%@", p.name);
打印结果为:jack123
当使用strong修饰属性的时候,属性的setter方法会直接强引用该对象,这样,当原对象的值发生改变时,新对象的属性也会改变
@property (nonatomic, strong) NSString *name;//当调用上面的strong时,等价于下面代码- (void)setName:(NSString *)name{_name = name;}
对NSString使用copy是用来保护其封装性,因为传递给设置方法的新值可能是NSMutableString类型,此时若不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份不可变的字符串,确保对象中的字符串不会无意间改动。只要实现属性所用的对象是可变的,就应该在设置新属性值时拷贝一份