最近感觉oc很好玩,所以自己弄来玩玩。
其中部分资源及概念来源于各种书籍教程及互联网。
自学笔记仅记录自己操作及实践的过程并分享。
因本人水平有限,不保证内容的正确性。
如有错误或侵犯,实属意外,请联系我修改或删除。
设有NSMutableArray的2个对象dataArray1和dataArray2。
那么语句
dataArray2=dataArray1;
[dataArray2 removeObjectAtIndex:0];
将从这两个变量引用的同一个数组中删除第一个元素。
1.copy和mutableCopy方法
Foundation实现了名为copy和mutableCopy的方法,可以使用这些方法创建对象的副本。通过实行一个符合<NSCopying>协议(用来制作副本)的方法来完成此任务。
那么语句
dataArray2=[dataArray1 mutableCopy];
在内存中创建了一个新的dataArray副本,并复制了它所有的元素。随后,执行语句
[dataArray2 removeObjectAtIndex: 0];
删除了dataArray2中的第一个元素但却不删除dataArray1中的第一个元素。
2.浅复制和深复制
设dataArray1由可变字符串填充。
那么dataArray2=[dataArray1 mutableCopy];
[dataArray[0] appendString: @"Fix"];
则dataArray1和dataArray2的第一个元素都将被改变。
因为mutableCopy复制数组时,在内存中为新的数组对象分配了空间,并且将单个元素复制到了新数组中,而将数组中的每个元素复制到新位置,意味着仅将引用复制到新位置。就是2个数组的元素都指向同一个字符串的内存。
若要为每个元素创建不同的副本,则需要深复制,深复制并不是默认执行的,可以通过“归档”功能来实现对象的深复制。
而语句
NSMutableString *mStr = [NSMutableSting stringWithString: dataArray1[0]];
[mStr appendString: @"Fix"];
[dataArray2 replaceObjectAtIndex: 0 withObject: mStr];
可以仅让dataArray1的第一个元素改变,而dataArray2的第一个元素不变,而且之后对 mStr中数据的修改也将影响到dataArray2的第一个元素。
3.实现<NSCopying>协议
实现<NSCopying>协议时还必须要实现copyWithZone:方法来响应copy消息。如果想要区分可变和不可变副本还需要根据<NSMutableCopying>协议实现mutableCopyWithZone:方法。产生可变副本并不需要对象本身也是可变的(反之亦然)。
@interface Fraction:NSObject <NSCopying>
-(id) CopyWithZone: (NSZone *) zone
{
Fraction *newFraction = [[Fraction allocWithZone: zone] init];
[newFraction setTo: numerator over: denominator];
return newFraction;
}
参数zone与不同的存储区有关,你可以在程序中分配并使用这些存储区。只有在要编写要分配大量内存的应用程序并且想要通过将空间分配分组到这些存储区中来优化内存分配时,才需要处理这些zone参数。可以使用传给copyWithZone:的值,并将他传给名为allocWithZone:的内存方法。这个方法在指定存储区中分配内存。
如果你的类能产生子类,那么copyWithZone:的方法将被继承这种情况下。
语句
Fraction *newFraction = [[Fraction allocWithZone: zone] init];
要改为
id newFraction = [[[self class] allocWithZone: zone] init];
如果编写一个类的copyWithZone:方法,而该类的超类也实现了<NSCopying>协议,那么应该先调用超类的copy方法以复制继承来的实例变量。然后复制添加到该类的附加实例变量。