iOS深複製和淺複製
淺複製範例程式碼:
NSMutableArray *mArray = [NSMutableArray arrayWithObjects: [NSMutableString stringWithString: @"origionA"], [NSMutableString stringWithString: @"origionB"], [NSMutableString stringWithString: @"origionC"], nil]; NSMutableArray *mArrayCopy = [mArray mutableCopy]; NSMutableString *string = [mArray objectAtIndex:0]; [string appendString:@"Append"]; [mArrayCopy removeObjectAtIndex:1]; NSLog(@"object.name = %@",mArray); NSLog(@"object.name = %@",mArrayCopy);
列印結果:
2015-04-23 15:18:15.151 AppTest[14507:122304] object.name = (
origionAAppend,
origionB,
origionC
)
2015-04-23 15:18:15.151 AppTest[14507:122304] object.name = (
origionAAppend,
origionC
)
說明:
Foundation類實現了名為copy和mutableCopy的方法,可以使用這些方法建立對象的副本,通過實現一個符合協議(如下代碼)的方法來完成這個工作,如果必須區分要產生的對象是可變副本還是不可變副本,那麼通過協議來產生不可變副本,通過協議來產生可變副本。
然而Foundation類的copy和mutableCopy方法,預設情況下只是對對象建立的一個新的引用,他們都指向同一塊記憶體,也就是淺複製。因此就會出現上面的結果。
@protocol NSCopying- (id)copyWithZone:(NSZone *)zone;@end@protocol NSMutableCopying- (id)mutableCopyWithZone:(NSZone *)zone;@end
深複製範例程式碼:
@interface DemoObject : NSObject@property (strong, nonatomic) NSString *name;@end@implementation DemoObject- (id)copyWithZone:(NSZone *)zone{ DemoObject* object = [[[self class] allocWithZone:zone]init]; return object; }@end
NSMutableArray *mArray = [NSMutableArray arrayWithObjects: [NSMutableString stringWithString: @"origionA"], [NSMutableString stringWithString: @"origionB"], [NSMutableString stringWithString: @"origionC"], nil]; NSMutableArray *mArrayCopy = [mArray mutableCopy]; NSMutableString *string = [mArray objectAtIndex:0]; [string appendString:@"Append"]; [mArrayCopy removeObjectAtIndex:1]; NSLog(@"object.name = %@",mArray); NSLog(@"object.name = %@",mArrayCopy);
列印結果:
2015-04-23 15:18:15.150 AppTest[14507:122304] object.name = object
2015-04-23 15:18:15.151 AppTest[14507:122304] newObject.name = newObject
說明:
自訂類中,必須實現或者協議並實現copyWithZone:或者mutableCopyWithZone:方法,才能響應copy和mutableCopy方法來複製對象。
參數zone與不同的儲存區有關,你可以在程式中分配並使用這些儲存區,只有在編寫要分配大量記憶體的應用程式並且想要通過將空間分配分組到這些儲存區中來最佳化記憶體配置時,才需要處理這些zone。可以使用傳遞給copyWithZone:的值,並將它傳給名為allocWithZone:的記憶體配置方法。這個方法在指定儲存區中分配記憶體。