一、数据源是NSMutableArray类型
@property(nonatomic, copy) NSMutableArray *aCopyMutArray;
@property(nonatomic, copy) NSArray *aCopyArray;
@property(nonatomic, strong) NSMutableArray *aStrongMutArray;
@property(nonatomic, strong) NSArray *aStrongArray;
首先创建了四个不同类型的数组对象
并赋上相同的值,可变型的数组
NSMutableArray *testArray = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
self.aCopyArray = testArray;
self.aStrongArray = testArray;
self.aCopyMutArray = testArray;
self.aStrongMutArray = testArray;
[testArray addObject:@"3"];
NSLog(@"=================step 1 = =========");
[self printArrays];
2018-03-12 16:44:33.839259+0800 Nunca[10196:1294488] =================step 1 = =========
2018-03-12 16:44:33.839567+0800 Nunca[10196:1294488] testArray = (
1,
2,
3
),isa = 0x600000246ed0
2018-03-12 16:44:33.839729+0800 Nunca[10196:1294488] aCopyArray = (
1,
2
),isa = 0x600000229b80
2018-03-12 16:44:33.839962+0800 Nunca[10196:1294488] aStrongArray = (
1,
2,
3
),isa = 0x600000246ed0
2018-03-12 16:44:33.840212+0800 Nunca[10196:1294488] aCopyMutArray = (
1,
2
),isa = 0x60000022a5a0
2018-03-12 16:44:33.840343+0800 Nunca[10196:1294488] aStrongMutArray = (
1,
2,
3
),isa = 0x600000246ed0
改变testArray的值,可见以strong修饰的对象指针指向的是同testArray同一块内存,而以copy修饰的对象则被分配了新的内存
NSLog(@"=================step 2 = =========");
if ([self.aCopyMutArray isKindOfClass:[NSMutableArray class]]) {
[self.aCopyMutArray addObject:@"4"];
NSLog(@"aCopyMutArray.class = NSMutableArray");
} else {
NSLog(@"aCopyMutArray.class = NSArray");
}
if ([self.aStrongArray isKindOfClass:[NSMutableArray class]]) {
void (*imp) (id,SEL,id) = (void (*)(id,SEL,id))[self.aStrongArray methodForSelector:@selector(addObject:)];
imp(self.aStrongArray,@selector(addObject:),@"4");
NSLog(@"aStrongArray.class = NSMutableArray");
} else {
NSLog(@"aStrongArray.class = NSArray");
}
[self printArrays];
2018-03-12 16:44:33.840434+0800 Nunca[10196:1294488] =================step 2 = =========
2018-03-12 16:44:33.840638+0800 Nunca[10196:1294488] aCopyMutArray.class = NSArray
2018-03-12 16:44:33.840850+0800 Nunca[10196:1294488] aStrongArray.class = NSMutableArray
2018-03-12 16:44:33.841007+0800 Nunca[10196:1294488] aCopyArray = (
1,
2
),isa = 0x600000229b80
2018-03-12 16:44:33.841099+0800 Nunca[10196:1294488] aStrongArray = (
1,
2,
3,
4
),isa = 0x600000246ed0
2018-03-12 16:44:33.841277+0800 Nunca[10196:1294488] aCopyMutArray = (
1,
2
),isa = 0x60000022a5a0
2018-03-12 16:44:33.841462+0800 Nunca[10196:1294488] aStrongMutArray = (
1,
2,
3,
4
),isa = 0x600000246ed0
aCopyMutArray 虽然注明的是NSMutableArray类型,但由于copy属性,实际上是不可变类型,aStrongArray虽然标明是NSArray类型,但由于strong属性,实际上的真实类型是跟数据源(testArray)保持一致。
二、数据源是NSArray类型
NSArray *testArray = [NSArray arrayWithObjects:@"1",@"2", nil];
self.aCopyArray = testArray;
self.aStrongArray = testArray;
self.aCopyMutArray = [NSMutableArray arrayWithArray:testArray];
self.aStrongMutArray = [NSMutableArray arrayWithArray:testArray];
NSLog(@"=================step 1 = =========");
[self printArrays];
2018-03-12 16:59:21.242880+0800 Nunca[10595:1312829] =================step 1 = =========
2018-03-12 16:59:21.243138+0800 Nunca[10595:1312829] testArray = (
1,
2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.243740+0800 Nunca[10595:1312829] aCopyArray = (
1,
2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.244087+0800 Nunca[10595:1312829] aStrongArray = (
1,
2
),isa = 0x60000023b7a0
2018-03-12 16:59:21.244433+0800 Nunca[10595:1312829] aCopyMutArray = (
1,
2
),isa = 0x60000002f780
2018-03-12 16:59:21.244684+0800 Nunca[10595:1312829] aStrongMutArray = (
1,
2
),isa = 0x600000243240
可见,当数据源是不可变类型时,不管对象是用strong还是用copy修饰,都会指向数据源同一块内存,不会再新创建
NSLog(@"=================step 2 = =========");
if ([self.aCopyMutArray isKindOfClass:[NSMutableArray class]]) {
[self.aCopyMutArray addObject:@"4"];
NSLog(@"aCopyMutArray.class = NSMutableArray");
} else {
NSLog(@"aCopyMutArray.class = NSArray");
}
if ([self.aStrongMutArray isKindOfClass:[NSMutableArray class]]) {
[self.aStrongMutArray addObject:@"4"];
NSLog(@"aStrongMutArray.class = NSMutableArray");
} else {
NSLog(@"aStrongMutArray.class = NSArray");
}
2018-03-12 16:59:21.244815+0800 Nunca[10595:1312829] =================step 2 = =========
2018-03-12 16:59:21.244989+0800 Nunca[10595:1312829] aCopyMutArray.class = NSArray
2018-03-12 16:59:21.245375+0800 Nunca[10595:1312829] aStrongMutArray.class = NSMutableArray
以copy修饰的aCopyMutArray仍然是不可变类型
结论:
- 当源数据与想持有的对象都是NSArray类型时,直接用strong或copy修饰都可以,效果也是一样;
- 当源数据为NSMutableArray类型,想持有的对象为NSArray时,用copy修饰;
- 当源数据为NSArray或NSMutableArray类型,想持有的对象为NSMutableArray时,用strong修饰对象并通过 [NSMutableArray arrayWithArray:testArray] 赋值,即可保证对象的可变性又能摆脱源数据变化时带来的影响。