`

iOS中浅拷贝与深拷贝

 
阅读更多

详情见: http://www.cnblogs.com/scorpiozj/archive/2011/01/25/1944496.html

 

1. 系统的非容器类对象 

    对于系统的非容器类对象,我们可以认为,如果对一不可变对象复制,copy是指针复制(浅拷贝)和mutableCopy就是对象复制(深拷贝)。如果是对可变对象复制,都是深拷贝,但是copy返回的对象是不可变的。

 

2. 系统的容器类对象

    NSArrayNSDictionary等。对于容器类本身,上面讨论的结论也是适用的,需要探讨的是复制后容器内对象的变化。

// copy返回不可变对象,mutablecopy返回可变对象
NSArray *array1 = [NSArray arrayWithObjects:@"a",@"b",@"c",nil];
   
NSArray *arrayCopy1 = [array1 copy];
//arrayCopy1是和array同一个NSArray对象(指向相同的对象),包括array里面的元素也是指向相同的指针
    
NSLog(@"array1 retain count: %d",[array1 retainCount]);
NSLog(@"array1 retain count: %d",[arrayCopy1 retainCount]);

NSMutableArray *mArrayCopy1 = [array1 mutableCopy];
//mArrayCopy1是array1的可变副本,指向的对象和array1不同,但是其中的元素和array1中的元素指向的是同一个对象。mArrayCopy1还可以修改自己的对象
   
[mArrayCopy1 addObject:@"de"];
[mArrayCopy1 removeObjectAtIndex:0];

     array1和arrayCopy1是指针复制,而mArrayCopy1是对象复制,mArrayCopy1还可以改变期内的元素:删除或添加。但是注意的是,容器内的元素内容都是指针复制。

 

下面用另一个例子来测试一下。

NSArray *mArray1 = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"a"],@"b",@"c",nil];
 
NSArray *mArrayCopy2 = [mArray1 copy];
NSLog(@"mArray1 retain count: %d",[mArray1 retainCount]);
NSMutableArray *mArrayMCopy1 = [mArray1 mutableCopy];
NSLog(@"mArray1 retain count: %d",[mArray1 retainCount]);
   
//mArrayCopy2,mArrayMCopy1和mArray1指向的都是不一样的对象,但是其中的元素都是一样的对象——同一个指针
//一下做测试
NSMutableString *testString = [mArray1 objectAtIndex:0];
   
//testString = @"1a1";//这样会改变testString的指针,其实是将@“1a1”临时对象赋给了testStrin
[testString appendString:@" tail"];//这样以上三个数组的首元素都被改变了

 

 由此可见,对于容器而言,其元素对象始终是指针复制。如果需要元素对象也是对象复制,就需要实现深拷贝。

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Articles/Copying.html

 

NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"first"],[NSString stringWithString:@"b"],@"c",nil];
NSArray *deepCopyArray=[[NSArray alloc] initWithArray: array copyItems: YES];
NSArray* trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject: array]];

    trueDeepCopyArray是完全意义上的深拷贝,而deepCopyArray则不是,对于deepCopyArray内的不可变元素其还是指针复制。或者我们自己实现深拷贝的方法。因为如果容器的某一元素是不可变的,那你复制完后该对象仍旧是不能改变的,因此只需要指针复制即可。除非你对容器内的元素重新赋值,否则指针复制即已足够。

 

3. 自定义对象

如果是我们定义的对象,那么我们自己要实现NSCopying,NSMutableCopying这样就能调用copymutablecopy了。举个例子:

@interface MyObj : NSObject<NSCopying,NSMutableCopying>
{
         NSMutableString *name;
         NSString *imutableStr;
         int age;
}
@property (nonatomic, retain) NSMutableString *name;
@property (nonatomic, retain) NSString *imutableStr;
@property (nonatomic) int age;
 
@end
 
@implementation MyObj
@synthesize name;
@synthesize age;
@synthesize imutableStr;
- (id)init
{
         if (self = [super init])
         {
                   self.name = [[NSMutableString alloc]init];
                   self.imutableStr = [[NSString alloc]init];
                   age = -1;
         }
         return self;
}
 
- (void)dealloc
{
         [name release];
         [imutableStr release];
         [super dealloc];
}
- (id)copyWithZone:(NSZone *)zone
{
         MyObj *copy = [[[self class] allocWithZone:zone] init];
         copy->name = [name copy];
         copy->imutableStr = [imutableStr copy];
//       copy->name = [name copyWithZone:zone];;
//       copy->imutableStr = [name copyWithZone:zone];//
         copy->age = age;
 
         return copy;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
         MyObj *copy = NSCopyObject(self, 0, zone);
         copy->name = [self.name mutableCopy];
         copy->age = age;
         return copy;
}
@end

 

分享到:
评论

相关推荐

    通过源码分析iOS中的深拷贝与浅拷贝

    在iOS开发中,深拷贝和浅拷贝是两个关键概念,它们涉及到对象复制时内存管理的细节。本文将从源码角度深入解析这两种拷贝方式。 首先,我们需要明确深拷贝和浅拷贝的基本定义。浅拷贝,也称为指针拷贝,意味着拷贝...

    浅析iOS中的浅拷贝和深拷贝(copy和mutableCopy)

    在iOS开发中,了解浅拷贝和深拷贝的概念至关重要,因为它们直接影响到对象的生命周期和内存管理。本文将深入浅析iOS中的`copy`和`mutableCopy`方法,以及它们与`retain`操作的区别。 首先,`copy`方法用于创建一个...

    copy的使用(深拷贝、浅拷贝)

    让我们深入探讨一下深拷贝与浅拷贝的概念及其应用场景。 ### 浅拷贝(Shallow Copy) 浅拷贝是创建一个新对象,这个新对象含有原对象的所有元素,但这些元素只是原始对象中的引用。也就是说,如果原始对象包含可变...

    ios-深拷贝对象.zip

    其中,深拷贝是数据持久化过程中的一个关键概念,特别是在处理复杂对象时,确保对象的独立性与原始数据的完整性。本资料“ios-深拷贝对象.zip”可能包含了关于如何在Objective-C或Swift中实现深拷贝的实践示例,特别...

    ios中深浅拷贝的讲解

    ios中深浅拷贝的讲解,通俗移动。深浅拷贝是ios开发人员面试经常会被问到的知识点,看了本文档,相信你回答ios中的深浅拷贝有不一样的认识。

    IOS深浅拷贝例子

    在iOS开发中,深拷贝和浅拷贝是Objective-C中的重要概念,主要与对象的内存管理机制有关。本文将详细解析这两个概念,并通过实际的代码示例来展示它们的区别和可能带来的意外结果。 首先,我们需要理解什么是拷贝。...

    iOS深浅拷贝例子

    在iOS开发中,深拷贝和浅拷贝是两个重要的概念,主要涉及到对象复制时内存管理的问题。这两个术语经常在讨论Objective-C中的`NSCopying`和`NSMutableCopying`协议时出现,以及Swift中的`Copyable`和`MutableCopyable...

    ios内存管理之深浅拷贝

    在iOS中,拷贝通常指的是对象复制,分为浅拷贝(Shallow Copy)和深拷贝(Deep Copy)两种: 1. 浅拷贝:浅拷贝只是复制对象的指针,不创建新的实例。也就是说,原对象和拷贝对象共享同一块内存空间。因此,如果...

    iOS中深拷贝与浅拷贝

    iOS中深拷贝与浅拷贝 浅拷贝 浅拷贝并不是拷贝对象本身,而是对...深拷贝与浅拷贝的本质区别 在于是否在堆内存中开辟新的内存空间。 注意 所有继承于NSObject的class都声明了copy和mutableCopy,但是并没有实现NSCopyi

    详解iOS的深浅拷贝

    在iOS开发中,深拷贝和浅拷贝是Objective-C(OC)中处理对象复制时两个重要的概念。本文将深入探讨这两种拷贝方式以及相关的知识点,帮助开发者理解它们的差异和应用场景。 首先,OC的对象拷贝主要有三种方式:浅...

    C/C++ 浅拷贝和深拷贝的实例详解

    C/C++ 浅拷贝和深拷贝的实例详解 ...在iOS开发中也会涉及到浅拷贝和深拷贝,简而言之: 浅拷贝:拷贝指针变量的值 深拷贝:拷贝指针所指向内存空间 不过这次我们通过C语言来实现: //声明一个结构体 typedef struct P

    IOS ObjectiveC中的赋值与对象拷贝

    本篇文章将深入探讨Objective-C中的赋值与对象拷贝,特别是深拷贝和浅拷贝的概念。 首先,我们要了解赋值操作(Assignment)。Objective-C中有两种类型的对象:基本数据类型(如结构体)和基于NSObject的对象。对于...

    ios笔试题(面试)

    浅拷贝与深拷贝的区别 浅拷贝和深拷贝是对象复制时常见的两种方式,尤其在处理复杂数据结构如数组、字典等时尤为重要。 - **浅拷贝**:创建一个新对象,这个新对象对字段的引用仍然指向原有的对象,所以对于引用...

    iOS内存管理1

    深拷贝和浅拷贝是iOS内存管理中两个重要的概念。深拷贝是指创建一个对象的完全副本,而浅拷贝是指创建一个对象的引用。例如,NSMutableArray的mutableCopy方法可以创建一个浅拷贝,而深拷贝需要使用专门的方法来实现...

    详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)

    在Java编程中,深拷贝和浅拷贝是两种复制对象的方法,它们涉及到对象的内存管理以及对象引用的处理。本文将深入探讨这两种拷贝方式,并着重讲解如何通过重写`clone()`方法以及使用序列化来实现深拷贝。 1. 浅拷贝:...

    ios的面试题目

    8. **浅拷贝与深拷贝**: - 浅拷贝:只复制对象的引用,不复制对象本身。如果拷贝的对象被修改,原始对象也会受到影响。 - 深拷贝:复制对象本身,拷贝和原始对象在内存中是独立的。修改拷贝的对象不会影响原始...

Global site tag (gtag.js) - Google Analytics