objective-c中的深、浅拷贝

浅复制:只复制指向对象的指针,而不复制引用对象本身。计数器+1 ,就像比如retain

深层复制:复制引用对象本身。计数器不变,产生新对象

retain:始终是浅复制。引用计数每次加一。返回对象是否可变与被复制的对象保持一致。

copy:对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,引用计数每次加一。始终返回一个不可变对象。

mutableCopy:始终是深复制,引用计数不改变。始终返回一个可变对象。

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {

    NSMutableArray *array1=[NSMutableArray arrayWithObjects:@"two day", nil];
    NSMutableArray *array2=[array1 copy];
    NSArray *array3=[array2 copy];
    NSArray *array4=[array2 retain];
    NSMutableArray *array5=[array1 retain];
    NSMutableArray *array6=[array1 mutableCopy];
    NSArray *array7=[array2 mutableCopy];
    NSLog(@"-------------");
    NSLog(@"array1:%@ %p",array1, array1);
    NSLog(@"array2:%@ %p",array2, array2);
    NSLog(@"array3:%@ %p",array3, array3);
    NSLog(@"array4:%@ %p",array4, array4);
    NSLog(@"array5:%@ %p",array5, array5);
    NSLog(@"array6:%@ %p",array6, array6);
    NSLog(@"array7:%@ %p",array7, array7);
    NSLog(@"-------------");
    return 0;
}

源代码

2015-04-01 20:46:23.131 04-01-person[2204:165655] -------------
2015-04-01 20:46:23.132 04-01-person[2204:165655] array1:(
    "two day"
) 0x100114570
2015-04-01 20:46:23.133 04-01-person[2204:165655] array2:(
    "two day"
) 0x100114700
2015-04-01 20:46:23.133 04-01-person[2204:165655] array3:(
    "two day"
) 0x100114700
2015-04-01 20:46:23.133 04-01-person[2204:165655] array4:(
    "two day"
) 0x100114700
2015-04-01 20:46:23.133 04-01-person[2204:165655] array5:(
    "two day"
) 0x100114570
2015-04-01 20:46:23.133 04-01-person[2204:165655] array6:(
    "two day"
) 0x1001150d0
2015-04-01 20:46:23.134 04-01-person[2204:165655] array7:(
    "two day"
) 0x100115b00
2015-04-01 20:46:23.134 04-01-person[2204:165655] -------------
Program ended with exit code: 0

运行结果

数组类型转换:

1、不可变对象→可变对象的转换:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    NSArray *array01=[NSArray arrayWithObjects:@"zhang",@"wang",@"li", nil];

    NSMutableArray  *array02=[array01 mutableCopy]; //mutableCopy始终返回一个可变对象

    NSLog(@"array01: %@  %p",array01,array01);
    NSLog(@"array02: %@  %p",array02,array02);
    return 0;
}

源代码

2015-04-01 21:00:28.218 04-01-person[2252:170414] array01: (
    zhang,
    wang,
    li
)  0x100106c80
2015-04-01 21:00:28.220 04-01-person[2252:170414] array02: (
    zhang,
    wang,
    li
)  0x1001076d0
Program ended with exit code: 0

运行结果

2、可变对象→不可变对象的转换:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    NSMutableArray *array1   = [NSMutableArray arrayWithObjects:@"zhang",@"wang",@"li", nil];
    NSArray *array2=[array1   copy];//copy对于可变对象为深复制,引用计数不改变;对于不可变对象是浅复制,引用计数每次加一。始终返回一个不可变对象
    NSLog(@"array1: %@  %p",array1,array1);
    NSLog(@"array2: %@  %p",array2,array2);
    return 0;
}

源代码

2015-04-01 21:03:45.349 04-01-person[2263:171615] array1: (
    zhang,
    wang,
    li
)  0x100112900
2015-04-01 21:03:45.350 04-01-person[2263:171615] array2: (
    zhang,
    wang,
    li
)  0x1001133b0

运行结果

3、可变对象→可变对象的转换(不同指针变量指向不同的内存地址):

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {

    NSMutableArray *array1= [NSMutableArray arrayWithObjects:@"zhang",@"wang",@"li", nil];

    NSMutableArray *array2=[array1 mutableCopy];
    NSLog(@"array1: %@  %p",array1,array1);
    NSLog(@"array2: %@  %p",array2,array2);
    return 0;
}

源代码

2015-04-01 20:57:41.732 04-01-person[2243:169571] array1: (
    zhang,
    wang,
    li
)  0x100114570
2015-04-01 20:57:41.734 04-01-person[2243:169571] array2: (
    zhang,
    wang,
    li
)  0x100115020
Program ended with exit code: 0

运行结果

4、同类型对象之间的指针复制(不同指针变量指向同一块内存地址):

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {

    NSArray *array1=[NSArray arrayWithObjects:@"one",@"two",@"three", nil];
    NSArray *array2=[array1 copy];
    NSLog(@"array1: %@  %p",array1,array1);
    NSLog(@"array2: %@  %p",array2,array2);
    return 0;
}

源代码

2015-04-01 20:53:07.398 04-01-person[2217:167996] array1: (
    one,
    two,
    three
)  0x1006069a0
2015-04-01 20:53:07.399 04-01-person[2217:167996] array2: (
    one,
    two,
    three
)  0x1006069a0
Program ended with exit code: 0

运行结果

当多个指针同时指向同一块内存区域,那么这些个指针同时拥有对该内存区的所有权。所有权的瓜分过程,这时候就要用到浅拷贝了。

 

时间: 2024-11-10 07:49:20

objective-c中的深、浅拷贝的相关文章

oc中深拷贝与浅拷贝

shallow 浅拷贝       Deep深拷贝 1.产生一个新对象,对象的内容与源对象相同 2.源对象与新对象使用不同的内存区域 3.需要NSCopying 或者NSMutableCopying协议才能使用复制功能 ? 4.Fundation中得基础数据类型如Nsstring.NSNumber 等都实现了NSCopying 5.新对象的引用计数为1 6.copy与mutableCopy的区别 copy返回不可变对象(包括可变对象在内) ? mutableCopy返回可变对象 7.浅拷贝只复制

c++深/浅拷贝 &amp;&amp; 构造函数析构函数调用顺序练习题

1.深/浅拷贝 编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝.浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟内存,这就会使得程序运行出现内存错误,如此,当对象析构的时候,会delete多次同一块内存区域,发生错误.这也就是为什么,必要的时候需要我们自己编写拷贝构造函数和重载赋值运算符,让它变成深拷贝,深拷贝即在copy指针的时候不是简单做值copy,而是还要开辟内存. 2.构造函数析构函数调用顺序练习题

JS中深拷贝与浅拷贝的区别,实现深拷贝的几种方法

JS中深拷贝与浅拷贝的区别,实现深拷贝的几种方法 如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 此篇文章中也会简单阐述到栈堆,基本数据类型与引用数据类型,因为这些概念能更好的让你理解深拷贝与浅拷贝. 我们来举个浅拷贝例子: let a=[0,1,2,3,4], b=a; console.log(a===b); a[0]=1; console.log(a,b); 嗯?明明b复

objective C中的字符串(三)

holydancer原创,如需转载,请在显要位置注明: 转自holydancer的CSDN专栏,原文地址:http://blog.csdn.net/holydancer/article/details/7343561 objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的操作字符串,下面举几个例子: 1.创建: 直接利用等号赋值 NSString *

c++中深拷贝和浅拷贝问题

在C++中深拷贝和浅拷贝问题还是比较重要的,简单介绍一下深拷贝和浅拷贝的意思,在C++中类默认有六个函数,拷贝构造函数就包括在其中,对于在程序运行的过程中,如果程序中没有自定义拷贝构造函数,那么程序将会使用自己的默认构造函数,在这个过程中,称为浅拷贝,用户自定义的拷贝构造函数称为深拷贝. 以下面的实际例子来加以说明深拷贝和浅拷贝之间的主要区别: #include <iostream> #include<string> using namespace std; class A { p

iOS 浅谈:深.浅拷贝与copy.strong

深.浅拷贝 copy mutableCopy NSString NSString *string = @"汉斯哈哈哈"; // 没有产生新对象 NSString *copyString = [string copy]; // 产生新对象 NSMutableString *mutableCopyString = [string mutableCopy]; NSLog(@"string = %p copyString = %p mutableCopyString = %p&quo

objective C中继承、协议、分类和多态的实现

第一.objective C中继承的实现 在oc中只有实例变量会有权限控制,实例方法和类方法是没有权限控制的,这点与c++不同,OC默认的是protected,并且在声明权限控制时,没有分号 在OC中可以像C++一样用指针运算法来访问实例变量 Rectangle.h 文件代码: #import <Foundation/Foundation.h> @interface Rectangle : NSObject { int _width; int _height; } @property (non

objective C中的字符串

holydancer原创,如需转载,请在显要位置注明: 转自holydancer的CSDN专栏,原文地址:http://blog.csdn.net/holydancer/article/details/7343561 objective C中的字符串操作 在OC中创建字符串时,一般不使用C的方法,因为C将字符串作为字符数组,所以在操作时会有很多不方便的地方,在Cocoa中NSString集成的一些方法,可以很方便的操作字符串,下面举几个例子: 1.创建: 直接利用等号赋值 NSString *

Python中深拷贝与浅拷贝的区别

Python中深拷贝与浅拷贝的区别: 原创 2017年04月20日 16:58:35 标签: python / python两种拷贝 / 深拷贝浅拷贝 / 拷贝区别 1661 定义: 在Python中对象的赋值其实就是对象的引用.当创建一个对象,把它赋值给另一个变量的时候,python并没有拷贝这个对象,只是拷贝了这个对象的引用而已. 浅拷贝:拷贝了最外围的对象本身,内部的元素都只是拷贝了一个引用而已.也就是,把对象复制一遍,但是该对象中引用的其他对象我不复制 深拷贝:外围和内部元素都进行了拷贝

js中对象的浅拷贝和深拷贝的区别

js中对象的浅拷贝和深拷贝的区别 浅度拷贝:复制一层对象的属性,并不包括对象里面的为引用类型的数据,当改变拷贝的对象里面的引用类型时,源对象也会改变. 深度拷贝:重新开辟一个内存空间,需要递归拷贝对象里的引用,直到子属性都为基本类型.两个对象对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性. 数据的类型: 一般数据(值传递):字符,数值,布尔,undefined 拷贝(复制)时,传递的是值,修改新数据,不会影响老数据 复杂数据(引用传递):对象 拷贝(复制)时,传递的是内存地址的