浅谈ObjC的“深浅拷贝”

本文通过具体的代码示例,介绍了如何在Objective-C中实现深拷贝与浅拷贝,并探讨了它们之间的区别。虽然Objective-C本身并没有深浅拷贝的概念,但可以通过类似的方法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    ObjC里面应该是没有深浅拷贝这个概念,但是实际在用的过程中我发现了这样的问题,也就是当对象A和对象B同时指向内存中同一个内容时,对象B若改变了该值,则对象A也会相应的改变该值。这就出现了一个问题,而这个问题跟C++中的深浅拷贝的思想不约而同的一致。大致思想是这样,我们来通过一下几个代码来具体看看。

    有5个文件,分别是Point.h Point.m Rectangle.h Rectangle.m 和  main.m

    Rectangle里包含了Point对象。main是主函数。

    

// Point.h
#import <foundation/Foundation.h>

@interface XYPoint: NSObject

@property int x, y;

-(void) setX: (int) xVal andY: (int) yVal;

@end

// Point.m
#import "Point.h"

@implementation XYPoint

@synthesize x, y;

-(void) setX: (int) xVal andY: (int) yVal
{
  x = xVal;
  y = yVal;
}

@end


// Rectangle.h
#import <Foundation/Foundation.h>

@class XYPoint;
@interface Rectangle: NSObject

@property int width, height;

-(XYPoint*) origin;
-(void) setOrigin: (XYPoint*) pt;
-(void) setWidth: (int) w andHeight: (int) h;
-(void) setDeepOrigin: (XYPoint*) pt;
@end

// Rectangle.m
#import "Rectangle.h"
#import "Point.h"

@implementation Rectangle
{
  XYPoint* origin;
}

@synthesize width, height;

-(void) setWidth: (int) w andHeight: (int) h
{
  width = w;
  height = h;
}

-(void) setOrigin: (XYPoint*) pt
{
  origin = pt;
}

-(void) setDeepOrigin: (XYPoint*) pt
{
  if (!origin)
    origin = [[XYPoint alloc] init];
  [origin setX: [pt x] andY: [pt y]];
}

-(XYPoint*) origin
{
  return origin;
}
@end

// main.m
#import "Point.h"
#import "Rectangle.h"

int main (int argc, char* argv[])
{
  @autoreleasepool{
    Rectangle* rec = [[Rectangle alloc] init];
    XYPoint* ptr = [[XYPoint alloc] init];
    [ptr setX: 100 andY: 200];
    [rec setWidth: 5 andHeight: 8];
    [rec setDeepOrigin: ptr];
    NSLog(@"Rectangle w = %i, h = %i", [rec width], [rec height]); // rec.width is also OK.
    NSLog(@"Origin at (%i, %i)", [[rec origin] x], [[rec origin] y]);
    [ptr setX: 999 andY: 999];
    NSLog(@"深拷贝Origin at (%i, %i)", [[rec origin] x], [[rec origin] y]);
    
    [rec setOrigin: ptr];
    [ptr setX: 999 andY: 999];
    NSLog(@"浅拷贝Origin at (%i, %i)", [[rec origin] x], [[rec origin] y]);
  }
  return 0;
} 


    可以看到深浅拷贝的区别了。

    虽说ObjC中没有明确的深浅拷贝概念,但是C++的深浅拷贝思想可以移植到ObjC来。

    同时值得注意的是,这里还用到了一个C++组合(composition)的概念,也就是说,Point是作为Rectangle的成员的,而且在Rectangle的接口中声明了@class XYPoint后就不用导入Point的头文件了,系统会默认把Point作为一个类来处理。但是Point的成员函数和成员变量无法使用,因为系统此时只知道它是一个类,而不清楚它的成员函数和变量是什么,如果要引用它的成员函数和变量的话,那么就需要导入Point的头文件。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值