Copy MutableCopy方法
1、对immutable对象进行copy操作,是浅复制,mutableCopy操作时深复制。
2、对mutable对象进行copy和mutableCopy都是深复制。
3、copy返回的都是不可变对象, mutableCopy返回的都是可变对象
NSString
NSString *originString = @"origin";
NSString *copyString = [originString copy]; //浅复制复制后的对象不可变
NSMutableString *mCopyString = [originString mutableCopy];//深复制复制后的对象可变
NSLog(@"origin string %p %p", originString, &originString);
NSLog(@"copy string %p %p", copyString, ©String);
NSLog(@"mutableCopy string %p %p", mCopyString, &mCopyString);
// 输出 origin string 0x100d34e08 0x16f0d7e48
// 输出 copy string 0x100d34e08 0x16f0d7e40
// 输出 mutableCopy string 0x1c4446b40 0x16f0d7e38
NSString
NSMutableString *originString2 = [NSMutableString stringWithString:@"origin"];
NSString *copyString2 = [originString2 copy]; //深复制复制后的对象不可变
NSMutableString *mCopyString2 = [originString2 mutableCopy];//深复制复制后的对象可变
NSLog(@"origin string2 %p %p", originString2, &originString2);
NSLog(@"copy string2 %p %p", copyString2, ©String2);
NSLog(@"mutableCopy string2 %p %p", mCopyString2, &mCopyString2);
// 输出 origin string 0x1c805fc80 0x16f357e30
// 输出 copy string 0xa006e696769726f6 0x16f357e28
// 输出 mutableCopy string 0x1c805e9f0 0x16f357e20
NSArray
NSArray *originArray = @[@"a", @"b", @"c"];
NSArray *copyArray = [originArray copy];//浅复制复制后的对象不可变 此时等价于copyArray = originArray
NSMutableArray *mCopyArray = [originArray mutableCopy];//深复制复制后的对象可变
NSLog(@"origin Array %p %p", originArray, &originArray);
NSLog(@"copy Array %p %p", copyArray, ©Array);
NSLog(@"mutableCopy Array %p %p", mCopyArray, &mCopyArray);
// 输出 origin Array 0x1c405afa0 0x16f017df8
// 输出 copy Array 0x1c405afa0 0x16f017df0
// 输出 mutableCopy Array 0x1c405dac0 0x16f017de8
NSMutableArray
NSMutableArray *originArray2 = [NSMutableArray arrayWithObjects: @"a", @"b", @"c", nil];
NSArray *copyArray2 = [originArray2 copy];//深复制复制后的对象不可变
NSMutableArray *mCopyArray2 = [originArray2 mutableCopy];//深复制复制后的对象可变
NSLog(@"origin Array %p %p", originArray2, &originArray2);
NSLog(@"copy Array %p %p", copyArray2, ©Array2);
NSLog(@"mutableCopy Array %p %p", mCopyArray2, &mCopyArray2);
// 输出 origin Array 0x1c4055ba0 0x16f293e18
// 输出 copy Array 0x1c4055c00 0x16f293e10
// 输出 mutableCopy Array 0x1c4055d80 0x16f293e08
Copy关键字
1、属性里的copy和strong NSString *str 声明一般用copy,如果一个NSMutableString的 *sourceStr 赋值给NSString,copy会进行深复制然后传给NSString
2、如果是一个 NSString 的 *sourceStr 赋值给str,copy和strong效果一样
3、赋值string应该用self.xxx,如果直接用_xxx,copy属性无效,等同于strong效果
赋值NSString
赋值NSString无论是用的Copy还是strong都是浅拷贝。
@interface ViewController ()
@property (nonatomic, strong) NSString *strongString;
@property (nonatomic, copy) NSString *copyedString;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSString *string = @"abc";
self.strongString = string;
self.copyedString = string;
NSLog(@"origin string: %p, %p", string, &string);
NSLog(@"strong string: %p, %p", _strongString, &_strongString);
NSLog(@"copy string: %p, %p", _copyedString, &_copyedString);
//输出 origin string: 0x1003a4e08, 0x16fa67e48
//输出 strong string: 0x1003a4e08, 0x111e1ec00
//输出 copy string: 0x1003a4e08, 0x111e1ec08
}
@end
赋值NSMutableString
赋值NSMutableString用的Copy进行深复制。strong是浅复制
可以看到下面改变源string,strongString的值变为和源string一样,指向同一个内存单元。
而copyedString进行了深复制,不随string改变。
NSMutableString *string = [NSMutableString stringWithString:@"origin"];
self.strongString = string;
self.copyedString = string;
[string appendString:@"_append"];
NSLog(@"origin string: %p, %p, %@", string, &string, string);
NSLog(@"strong string: %p, %p, %@", _strongString, &_strongString, _strongString);
NSLog(@"copy string: %p, %p, %@", _copyedString, &_copyedString, _copyedString);
//输出 origin string: 0x1c04515b0, 0x16f6dfe48, origin_append
//输出 strong string: 0x1c04515b0, 0x11fd09f00, origin_append
//输出 copy string: 0xa006e696769726f6, 0x11fd09f08, origin
注意使用_.xxx赋值copy属性无效
可以看到下面改变源string,strongString和copyedString为和源string一样,3个都指向同一个内存单元。
NSMutableString *string = [NSMutableString stringWithString:@"origin"];
_strongString = string;
_copyedString = string;
[string appendString:@"_append"];
NSLog(@"origin string: %p, %p, %@", string, &string, string);
NSLog(@"strong string: %p, %p, %@", _strongString, &_strongString, _strongString);
NSLog(@"copy string: %p, %p, %@", _copyedString, &_copyedString, _copyedString);
//输出 origin string: 0x1c02586f0, 0x16f407e48, origin_append
//输出 strong string: 0x1c02586f0, 0x1011166f0, origin_append
//输出 copy string: 0x1c02586f0, 0x1011166f8, origin_append
赋值NSMutableArray
@interface ViewController ()
@property (nonatomic, strong) NSArray *strongArray;
@property (nonatomic, copy) NSArray *copyedArray;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *originArray = [NSMutableArray arrayWithObjects: @"a", @"b", @"c", nil];
self.strongArray = originArray;
self.copyedArray = originArray;
[originArray addObject:@"d"];
NSLog(@"origin Array %p %p %ld", originArray, &originArray, originArray.count);
NSLog(@"strong Array %p %p %ld", _strongArray, &_strongArray, _strongArray.count);
NSLog(@"copyed Array %p %p %ld", _copyedArray, &_copyedArray, _copyedArray.count);
//输出 origin Array 0x1c4458930 0x16f1e7e48 4
//输出 strong Array 0x1c4458930 0x1012299d0 4
//输出 copyed Array 0x1c44589c0 0x1012299d8 3
}
@end
总的来说,A属性加入copy关键字是作用是:如果将可变的外部变量B赋值给A时,将B进行深复制传给A,使得B改变时不影响A的值。
自定义对象Copy
需要实现NSCopying协议能使用Copy方法
//Test.h
#import <Foundation/Foundation.h>
@interface Test : NSObject<NSCopying>
@property (nonatomic, assign) int index;
@end
//Test.m
#import "Test.h"
@implementation Test
- (instancetype)copyWithZone:(NSZone *)zone {
Test *copy = [Test allocWithZone:zone];
copy.index = _index;//拷贝数据
return copy;
}
@end
直接赋值是指针赋值,指向同一个对象(内存单元),改变一个另外一个也变
Test *test1 = [Test new];
test1.index = 5;
Test *test2 = test1;
test2.index = 6;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
test1.index = 7;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
// 输出 test1: 0x1c000d4b0 6
// 输出 test2: 0x1c000d4b0 6
// 输出 test1: 0x1c000d4b0 7
// 输出 test2: 0x1c000d4b0 7
copy方法进行深复制 改变其中一个不影响另外一个
Test *test1 = [Test new];
test1.index = 5;
Test *test2 = [test1 copy];
test2.index = 6;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
test1.index = 7;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
// 输出 test1: 0x1c401ef30 5
// 输出 test2: 0x1c401f060 6
// 输出 test1: 0x1c401ef30 7
// 输出 test2: 0x1c401f060 6
使用copy属性关键字
#import "Test.h"
@interface ViewController ()
@property (nonatomic, copy) Test *copyedTest;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Test *orignTest = [Test new];
orignTest.index = 5;
self.copyedTest = orignTest;
_copyedTest.index = 6;
NSLog(@"orignTest: %p %d", orignTest, orignTest.index);
NSLog(@"copyedTest: %p %d", _copyedTest, _copyedTest.index);
orignTest.index = 7;
NSLog(@"orignTest: %p %d", orignTest, orignTest.index);
NSLog(@"copyedTest: %p %d", _copyedTest, _copyedTest.index);
// 输出 orignTest: 0x1c40165d0 5
// 输出 copyedTest: 0x1c4016610 6
// 输出 orignTest: 0x1c40165d0 7
// 输出 copyedTest: 0x1c4016610 6
}
@end
利用归档实现深复制
需要实现NSCoding协议
//Test.h
#import <Foundation/Foundation.h>
@interface Test : NSObject<NSCoding>
@property (nonatomic, assign) int index;
@end
//Test.m
#import "Test.h"
@implementation Test
- (void)encodeWithCoder:(NSCoder *)encoder {
[encoder encodeObject:[NSNumber numberWithInt:self.index] forKey:@"index"];
}
- (instancetype)initWithCoder:(NSCoder *)decoder {
self.index = [[decoder decodeObjectForKey:@"index"] intValue];
return self;
}
@end
Test *test1 = [Test new];
test1.index = 5;
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:test1];//归档
Test *test2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
test2.index = 6;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
test1.index = 7;
NSLog(@"test1: %p %d", test1, test1.index);
NSLog(@"test2: %p %d", test2, test2.index);
// 输出 test1: 0x1c400c370 5
// 输出 test2: 0x1c8009870 6
// 输出 test1: 0x1c400c370 7
// 输出 test2: 0x1c8009870 6
1116

被折叠的 条评论
为什么被折叠?



