1、 copy、mutableCopy方法
copy方法返回对象的不可修改的副本
mutableCopy方法返回的对象可修改的副本
1)、测试demo
int main(int argc, char * argv[]) {
@autoreleasepool {
NSMutableString *book = [NSMutableString stringWithString:@"chenyu"];
NSMutableString *bookCopy = [book mutableCopy];
[bookCopy replaceCharactersInRange:NSMakeRange(1, 2) withString:@"gong"];
NSLog(@"book is %@", book);
NSLog(@"bookCopy is %@", bookCopy);
NSString *str = @"chenyu";
NSMutableString *strCopy = [str mutableCopy];
[strCopy appendString:@"chenyu"];
NSLog(@"strCopy is:%@", strCopy);
//由于str2是不可变的,所以运行下面会报错
NSMutableString *str2 = [str copy];
NSLog(@"str copy chen is:%@", str2);
// [str2 appendString:@"chenyu"];
}
}
2)、运行结果
2018-07-15 19:03:35.564049+0800 cyTest[27254:9418105] book is chenyu
2018-07-15 19:03:35.565157+0800 cyTest[27254:9418105] bookCopy is cgongnyu
2018-07-15 19:03:35.566056+0800 cyTest[27254:9418105] strCopy is:chenyuchenyu
2018-07-15 19:03:35.566857+0800 cyTest[27254:9418105] str copy chen is:chenyu
2、NSCopying、NSMutableCopy协议
对象调用mutableCopy方法来复制自身的可变副本,需要类实现NSMutbaleCopying协议,让类实现mutableCopyWithZone方法demo可以看下下面写的浅复制
3、深复制和浅复制
我个人理解感觉浅复制是复制后的属性(指针变量)指向的地址都是同一块地址,当复制后的对象属性值发生变化的时候,原始值也发生了变化。
深复制就是复制后的属性(指针变量)指向的地址不是同一块地址,当复制后的对象属性值发生变化的时候,原始值不会发生变化。
1)、浅复制测试Demo
Dog.h
#import <Foundation/Foundation.h>
#ifndef Dog_h
#define Dog_h
@interface Dog : NSObject<NSCopying>
@property (nonatomic, strong) NSMutableString *name;
@property (nonatomic, assign) int age;
@end
#endif /* Dog_h */
Dog.m
#import <Foundation/Foundation.h>
#import "Dog.h"
@implementation Dog
@synthesize name;
@synthesize age;
-(id)copyWithZone:(NSZone *)zone
{
Dog *dog = [[[self class] allocWithZone:zone] init];
dog.name = self.name;
dog.age = self.age;
return dog;
}
@end
main.m
Dog *dog1 = [Dog new];
dog1.name = [NSMutableString stringWithString:@"chen"];
dog1.age = 1;
NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
//浅复制
Dog *dog2 = [dog1 copy];
// dog2.name = [NSMutableString stringWithString:@"li"];
[dog2.name replaceCharactersInRange:NSMakeRange(1, 2) withString:@"hel"];
dog2.age = 20;
NSLog(@"dog2.name is %@ and age is %d", dog2.name, dog2.age);
NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
2)、运行结果
2018-07-15 19:03:35.567556+0800 cyTest[27254:9418105] dog1.name is chen and age is 1
2018-07-15 19:03:35.567690+0800 cyTest[27254:9418105] dog2.name is cheln and age is 20
2018-07-15 19:03:35.567768+0800 cyTest[27254:9418105] dog1.name is cheln and age is 1
Dog.h文件一样
Dog.m文件有点变化
#import <Foundation/Foundation.h>
#import "Dog.h"
@implementation Dog
@synthesize name;
@synthesize age;
-(id)copyWithZone:(NSZone *)zone
{
Dog *dog = [[[self class] allocWithZone:zone] init];
// dog.name = self.name;
dog.name = [self.name mutableCopy];
dog.age = self.age;
return dog;
}
@end
main.m文件一样
Dog *dog1 = [Dog new];
dog1.name = [NSMutableString stringWithString:@"chen"];
dog1.age = 1;
NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
//深复制
Dog *dog2 = [dog1 copy];
// dog2.name = [NSMutableString stringWithString:@"li"];
[dog2.name replaceCharactersInRange:NSMakeRange(1, 2) withString:@"hel"];
dog2.age = 20;
NSLog(@"dog2.name is %@ and age is %d", dog2.name, dog2.age);
NSLog(@"dog1.name is %@ and age is %d", dog1.name, dog1.age);
4)、运行结果
2018-07-15 19:13:08.751335+0800 cyTest[27529:9427019] dog1.name is chen and age is 1
2018-07-15 19:13:08.751686+0800 cyTest[27529:9427019] dog2.name is cheln and age is 20
2018-07-15 19:13:08.751885+0800 cyTest[27529:9427019] dog1.name is chen and age is 1
4、setter方法的复制选项
我们setter方法复制选项的时候,如果加了copy属性,比如setName方法
-(void)setName : (NSMutableStrinfg *)name
{
self.name = [name copy];
}
#import <Foundation/Foundation.h>
#import "Dog.h"
@implementation Dog
@synthesize name;
@synthesize age;
@end
所以当对象设置了name属性的话,就不能再改变了,如下demo
Dog.h
#import <Foundation/Foundation.h>
#ifndef Dog_h
#define Dog_h
@interface Dog : NSObject
@property (nonatomic, copy) NSMutableString *name;
@property (nonatomic, assign) int age;
@end
#endif /* Dog_h */
Dog.m
#import <Foundation/Foundation.h>
#import "Dog.h"
@implementation Dog
@synthesize name;
@synthesize age;
@end
main.m
Dog *dog1 = [Dog new];
dog1.name = [NSMutableString stringWithString:@"chen"];
dog1.age = 1;
[dog1.name appendString:@"hello"];
运行结果
2018-07-15 19:22:17.736557+0800 cyTest[27853:9436238] -[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa0000006e6568634
2018-07-15 19:22:17.739655+0800 cyTest[27853:9436238] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSTaggedPointerString appendString:]: unrecognized selector sent to instance 0xa0000006e6568634'
*** First throw call stack:
(
0 CoreFoundation 0x0000000104fd61e6 __exceptionPreprocess + 294
1 libobjc.A.dylib 0x000000010466b031 objc_exception_throw + 48
2 CoreFoundation 0x0000000105057784 -[NSObject(NSObject) doesNotRecognizeSelector:] + 132
3 CoreFoundation 0x0000000104f58898 ___forwarding___ + 1432
4 CoreFoundation 0x0000000104f58278 _CF_forwarding_prep_0 + 120
5 cyTest 0x0000000103d60438 main + 600
6 libdyld.dylib 0x0000000108a2f955 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
很明显,报错了。