第二十六讲:Objective-C内存管理之深拷贝
继续上一讲的浅拷贝,深拷贝的区别在于是否拷贝对象中的引用对象1、创建一个数组array,将类Car创建三个对象并保存到数组array中,使用[ initWithArray:array]方法将array数组拷贝到array1中,修改array中的car元素,查看array1中的car是否发生变化;2、使用[ initWithArray:array copyItems:YES]方法将array拷贝到array2中,修改array中的car元素,查看array2中的car是否发生变化;
SACar.h
//
//SACar.h
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface SACar : NSObject <NSCopying>
@property (assign) NSString * name;
@property int year;
@end
SACar.m
//
//SACar.m
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import "SACar.h"
@implementation SACar
//***************************************NSCopying
- (id) copyWithZone:(NSZone *)zone {
SACar * c = [[[ allocWithZone:zone] init] autorelease];
c.name = self.name;
c.year = self.year;
return c;
}
//***************************************NSCopying_end
- (NSString *) description {
return ;
}
- (void) dealloc {
NSLog(@"%@ is dealloc", self.name);
self.name = nil;
;
}
@end
main.m
//
//main.m
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SACar.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableArray * array = [ init];
for (int i = 0; i < 3; i ++) {
SACar * car = [ init];
car.name = ;
car.year = 2000 + i;
;
;
}
NSLog(@"%@", array);
NSMutableArray * array1 = [ initWithArray:array];
[ setName:@"NewCar"];
NSLog(@"%@", array);
NSMutableArray * array2 = [ initWithArray:array copyItems:YES];
[ setName:@"SecondCar"];
NSLog(@"%@", array);
NSLog(@"%@", array2);
// ;
// ;
// ;
}
return 0;
}
运行结果:
2014-01-22 21:40:09.327 DeepCopy (
"Car0 age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 21:40:09.329 DeepCopy (
"NewCar age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 21:40:09.329 DeepCopy (
"NewCar age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 21:40:09.329 DeepCopy (
"SecondCar age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 21:40:09.330 DeepCopy Car2 is dealloc
2014-01-22 21:40:09.330 DeepCopy Car1 is dealloc
2014-01-22 21:40:09.330 DeepCopy SecondCar is dealloc
Program ended with exit code: 0结果表示:
进行浅拷贝后,修改array中的Car0为“NewCar”后,array与array1中的Car0都变成了NewCar;
进行深拷贝后,修改array2中的Car0为“SecondCar”后,array中的Car0依然为之前的NewCar;
array2打印出来的结果中,Car0被修改成SecondCar,并且array2被自动释放,array与array1却没有,为什么?
深拷贝还可以通过归档的方式来实现:
1、创建好的数组array归档到data中;
2、将data解档到array1中,该过程会将归档的数据读出重新加载到数组array1中;
3、需要注意的是:前面使用数组的copy方法,Car中的Name属性为assign,使用数组copy后会自动内存管理,但通过归档方式实现,解档时会报错,因此,在声明属性时,需要使用copy属性:@property(copy) NSString * name;
代码如下:
SACar.h
//
//SACar.h
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface SACar : NSObject <NSCopying, NSCoding>
@property (copy) NSString * name;
@property int year;
@end
SACar.m
//
//SACar.m
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import "SACar.h"
@implementation SACar
//***************************************NSCopying
- (id) copyWithZone:(NSZone *)zone {
SACar * c = [[[ allocWithZone:zone] init] autorelease];
c.name = self.name;
c.year = self.year;
return c;
}
//***************************************NSCopying_end
//***************************************NSCoding
- (void) encodeWithCoder:(NSCoder *)aCoder {
;
;
}
- (id) initWithCoder:(NSCoder *)aDecoder {
if (self = ) {
self.name = ;
self.year = ;
}
return self;
}
//***************************************NSCoding_end
- (NSString *) description {
return ;
}
- (void) dealloc {
NSLog(@"%@ is dealloc", self.name);
self.name = nil;
;
}
@end
main.m
//
//main.m
//DeepCopy
//
//Created by yusian on 14-1-22.
//Copyright (c) 2014年 yusian. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SACar.h"
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableArray * array = [ init];
for (int i = 0; i < 3; i ++) {
SACar * car = [ init];
car.name = ;
car.year = 2000 + i;
;
;
}
NSLog(@"%@", array);
NSData * data = ;
NSMutableArray * array1 = ;
[ setName:@"NewCar"];
NSLog(@"%@", array);
;
//;
}
return 0;
}
输出结果:
2014-01-22 22:46:06.956 DeepCopy (
"Car0 age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 22:46:06.958 DeepCopy (
"Car0 age is 2000",
"Car1 age is 2001",
"Car2 age is 2002"
)
2014-01-22 22:46:06.958 DeepCopy Car0 is dealloc
2014-01-22 22:46:06.959 DeepCopy Car1 is dealloc
2014-01-22 22:46:06.959 DeepCopy Car2 is dealloc
2014-01-22 22:46:06.959 DeepCopy NewCar is dealloc
2014-01-22 22:46:06.960 DeepCopy Car1 is dealloc
2014-01-22 22:46:06.960 DeepCopy Car2 is dealloc
Program ended with exit code: 0
同样的道理,通过归档进行深拷贝的对象不需要release,这与@autoreleasepool有关系,原因暂未知;
页:
[1]