IOS ObjectiveC中的赋值与对象拷贝
在开发过程中我们经常会遇到对象拷贝的问题,下面我们分别讨论赋值操作、对象拷贝、以及浅拷贝(Shallow copy)与深拷贝(Deep copy)的区别与各自的实现方式。
一、不同对象的赋值操作
Objective-C中有两类对象,一类是结构体(或者基本数据类型也算),另一类是NSObject对象。
对于结构体,代码直接会操作其实体,因此赋值操作会创建一个源对象的副本(一个新的对象);而对于NSObject对象,必须使用指针来操作对象,所以其赋值操作相当于复制了指针,而非对象,也就是说赋值操作使得源指针和新指针都指向同一个NSObject对象。这样讲有些难以理解,请看下面的代码:
// main.m
#import <Foundation/Foundation.h>
@interface TestObject : NSObject
{
@public
int x;
int y;
}
@end
@implementation TestObject
@end
typedef struct TestStruct
{
int x;
int y;
}
TestStruct;
int main(int argc, const char * argv[])
{
@autoreleasepool {
TestStruct ts1 = {100, 50};
NSLog(@"ts1: %p, %d, %d", &ts1, ts1.x, ts1.y);
TestStruct ts2 = ts1;
NSLog(@"ts2: %p, %d, %d", &ts2, ts2.x, ts2.y);
TestObject* to1 = [[[TestObject alloc] init] autorelease];
NSLog(@"to1: %p, %d, %d", to1, to1->x, to1->y);
TestObject* to2 = to1;
NSLog(@"to2: %p, %d, %d", to2, to2->x, to2->y);
}
return 0;
}
程序的运行结果如下:
ts1: 0x7fff63463898, 100, 50
ts2: 0x7fff63463890, 100, 50
to1: 0x7fc342d00370, 0, 0
to2: 0x7fc342d00370, 0, 0
程序代码首先定义了一个类TestObject(继承自NSObject),然后又定义了一个结构体TestStruct。这两者都包含两个整型的成员变量x和y。然后在main函数中,程序首先为TestStruct结构体ts1分配内存空间,并为其成员变量赋初值,x为100,y为50。然后通过NSLog函数打印出该结构体的地址和成员变量的值,即输出的第一行内容。接着,程序执行了赋值语句,将ts1赋值给另一个TestStruct结构体对象ts2,这条语句会为ts2分配另一块内存,然后把ts1的每个成员变量的值复制过来。第二行输出也可以看出来,地址不一样了,所以如果修改ts1的成员变量的值,是不会影响ts2的。
接着再来看TestObject。程序接着使用alloc静态方法分配了一块新的内存空间,然后通过init实例方法进行初始化(所有成员变量的值为0),最后将该内存空间的首地址返回。to1的实质就是一个指针,指向创建的TestObject对象。接着,程序将to1赋值给to2。to2也是一个指向TestObject对象的指针,其值与to1一样,即两者都指向同一个对象。所以在这种情况下,对to1的修改会同时影响to2。










