复制对象
-简单的赋值语句将对象赋值给另一个对象
origin = pt;
origin和pt都是带有两个整型实例变量x和y的XYPoint对象。这样的赋值结果仅仅是将对象pt的地址复制到origin中,在赋值操作结束时,两个变量指向同一个地址。改变origin的x和y值,会导致pt的x和y值同样改变,因为他们指向同一个对象。
-Foundation框架中对象的赋值
比如:dataArray2和dataArray都是NSMutableArray的对象:
dataArray2 = dataArray;
[dataArray2] removeObjectAtIndex:0];
会将这两个变量引用的同一个数组中的第一个元素删除。
copy和mutableCopy方法
Foundation类实现了名为copy和mutableCopy的方法,可以使用这些方法创建对象副本。通过实现一个符合协议的方法来完成。
copy消息
-拷贝对象如果是不可变对象,则拷贝结果为不可变
-拷贝对象如果是可变对象,则拷贝结果为不可变
-拷贝不可变对象相当于retain对象
-拷贝可变对象,会创建一个新的对象并且将新对象的计数器设置为1
mutableCopy消息
-若拷贝对象如果为不可变对象,则拷贝结果为可变
-若拷贝对象为可变对象,则拷贝结果为可变
-都生成了新的对象
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSArray *arr = [[[NSArray alloc] initWithObjects:@"1", nil] autorelease];
NSLog(@"arr = %ld arr = %p",arr.retainCount,arr);
NSMutableArray *arr2 = [[[NSMutableArray alloc]initWithObjects:@"1", nil] autorelease];
NSLog(@"arr2 = %ld arr2 = %p",arr2.retainCount,arr2);
//copy消息拷贝不可变对象相当于retain该对象
NSArray *arr1 = [[arr copy] autorelease];
NSLog(@"arr1= %ld arr1 = %p",arr1.retainCount,arr1); // 计数器+1 地址不变
//copy拷贝可变对象会生成新的对象,拷贝的结果为不可变对象
NSArray *arr3 = [[arr2 copy] autorelease];
NSLog(@"arr3 = %ld arr3 = %p",arr3.retainCount,arr3);
if (![arr3 isKindOfClass:[NSMutableArray class]]) {
NSLog(@"arr3 是NSArray类型");
}
//isMemberOfClass 是精准判断,只能是本类类型
//isKindOfClass 判断这个对象只要是本类或者是本类的子类,都会返回YES
//mutableCopy拷贝对象
NSArray *arr4 = [[[NSArray alloc] initWithObjects:@"1", nil] autorelease];
NSLog(@"arr4 = %ld arr4 = %p",arr4.retainCount,arr4);
//mutableCopy拷贝不可变对象,会产生新对象,并且拷贝所产生的对象为可变对象
NSMutableArray *arr5 = [[arr4 mutableCopy] autorelease];
NSLog(@"arr5 = %ld arr5 = %p",arr5.retainCount,arr5);
if ([arr5 isKindOfClass:[NSMutableArray class]]) {
NSLog(@"arr5 是NSMutableArray类型");
}
//mutablCopy拷贝可变对象
NSMutableArray *arr6 = [[[NSMutableArray alloc] initWithObjects:@"2", nil] autorelease];
NSLog(@"arr6 = %ld arr6 = %p",arr6.retainCount,arr6);
//mutablCopy拷贝可变对象,会产生可变的新对象
NSMutableArray *arr7 = [[arr6 mutableCopy]autorelease];
NSLog(@"arr7 = %ld arr7 = %p",arr7.retainCount,arr7);
}
return 0;
}
浅拷贝与深拷贝
-浅拷贝可以理解为简单指针赋值,新指针和旧指针指向同一片内存地址
-深拷贝可以理解为新指针和旧指针指向各自不同的内存地址
自定义对象拷贝
注意:自定义对象没有可变与不可变之分,所以自定义对象发送copy消息是浅拷贝,发送mubleCopy消息是深拷贝
自定义拷贝需要实现NSCopying或者NSMutableCopying协议
person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject<NSCopying,NSMutableCopying>//遵守协议
@property (nonatomic,copy)NSString *name;
@property (nonatomic,assign)NSInteger age;
@property (nonatomic,retain)NSMutableArray *arr;
@end
person.m
#import "Person.h"
@implementation Person
//NSZone这个内存类,zone代表了一块系统已经分配好的内存
//浅拷贝
-(id)copyWithZone:(NSZone *)zone{
//进行浅拷贝操作
return [self retain];
}
//深拷贝
-(id)mutableCopyWithZone:(NSZone *)zone{
//进行深拷贝操作
//alloc—》allocWithZone
Person *per = [[[self class] allocWithZone:zone] init];
//新对象成员变量也要分离出来,并且数据要和原对象一致
per.age = _age;
per.name = [[_name mutableCopy] autorelease];
per.arr = [[_arr mutableCopy] autorelease];
return per;
}
@end