【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝

对象的拷贝分为浅拷贝和深拷贝,浅拷贝就是只拷贝对象,但是属性不拷贝,拷贝出来的对象和原来的对象共用属性,即指向同一个属性地址,深拷贝则相当于不仅拷贝了一个对象还拷贝了它的属性,即完全是两个东西,只不过内容相同而已。

拷贝用到协议,如果这个类创建对象后,这个对象要被拷贝,那么这个类就需要用到拷贝协议,分两种:<NSCopying>和<NSMutableCopying>相当于一个是拷贝,另一个是拷贝后可修改。

(1)浅拷贝的案例。有一个Person类,它创建一个person1对象后,用person1再拷贝一个person2出来。

//Person类的Person.h文件
#import <Foundation/Foundation.h>
//因为这个类要支持拷贝,所以需要引入拷贝协议,有两种,后一种拷贝后可修改
@interface Person : NSObject<NSCopying,NSMutableCopying>
@property(nonatomic,copy) NSString* name;
@property(nonatomic,retain) NSNumber* age;
@end
//这是Person.m文件
#import "Person.h"
@implementation Person
//这是系统函数,可以直接拷贝过来
- (id)copyWithZone:(NSZone *)zone{
    Person *person=[[[self class]allocWithZone:zone]init]; //默认格式
    person.name=_name; //浅拷贝就是直接赋值即可
    person.age=_age;  //浅拷贝就是直接赋值即可
    return person;
}
@end
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"//记得引入头文件
int main(int argc, const char * argv[])
{
    @autoreleasepool {
        Person *person1=[[Person alloc]init];
        [email protected]"jack";
        [email protected];
        Person *person2=[person1 copy];
        NSLog(@"%p,%p",person1,person2);//输入两个对象地址,不同
        NSLog(@"%p,%p",person1.age,person2.age);//输出两个对象的属性地址,相同
    }
    return 0;
}

结果:

0x1002036f0,0x100200330 //不同
0x1227,0x1227 //相同

(2)深拷贝的案例。

按道理是只需要把Person.m里面的赋值语句改成下面的样子,就能实现深拷贝:

person.name=[_name copy];
person.age=[_age copy];

但是,因为cocoa优化过了,所以有如下规则:

a:如果是Foundation框架里地不可变对象,就是Array,NSString等创建的对象,直接用copy来拷贝相当于retain,也就是属性还是同一个;

b:如果是用mutableCopy来拷贝,不管是可变还是不可变对象,属性神马的都直接拷贝了一份,即真正意义上得拷贝,它拷贝出来的对象统统都是可变的;

c:如果是可变对象,我们用copy也能实现真正意义上的拷贝,但是拷贝出来的对象是不可变的。

所以,我们拿name实验(因为age没有mutableCopy)实现语句的修改:

person.name=[_name mutableCopy]
person.age=[_age copy];

然后再输出person1和person2的name属性的地址,发现就不同了。

总结:

浅拷贝和深拷贝在实际项目中不常用,可以做一般了解。

时间: 2024-10-19 13:44:10

【OC学习-26】对象的浅拷贝和深拷贝——关键在于属性是否可被拷贝的相关文章

对象复制 - 浅拷贝与深拷贝

前言 在前面的文章中,提到过Java之间如果发生了对象赋值,那么其意义是赋值的两个对象都指向同一片内存区域. 那么,如果我希望得到的是一份新的副本 - 即可以随意更改而不影响原始对象呢? 那就涉及到本文要探讨的话题 - 对象的浅拷贝与深拷贝. 浅拷贝 若对象之间发生浅拷贝,那么首先肯定的是会创建一个新的对象副本(这就不同与对象间的直接赋值). 然后所有域进行简单的直接复制 - 非对象域直接拷贝过来,对象域则拷贝此对象的地址(因为对象在java中的本质就是一个 "指针"). 如何进行浅拷

(一)Python入门-6面向对象编程:11对象的浅拷贝和深拷贝

对象的浅拷贝和深拷贝: 变量的赋值操作 只是形成两个变量,实际还是指向同一个对象. 浅拷贝 Python拷贝一般都是浅拷贝.拷贝时,对象包含的子对象内容不拷贝.因此,源对象 和拷贝对象会引用同一个子对象. 深拷贝 使用copy模块的 deepcopy 函数,递归拷贝对象中包含的子对象.源对象和拷贝对象 所有的子对象也不同. [操作] #测试对象的引用赋值,浅拷贝,深拷贝 import copy class MobilePhone: def __init__(self,cpu,screen): s

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

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

OC学习16——对象归档

转载自  OC学习篇之---归档和解挡 OC中的归档就是将对象写入到一个文件中,Java中的ObjectInputStream和ObjectOutputStream来进行操作的.当然在操作的这些对象都是需要实现一个接口:Serializable,同样的OC中操作的对象也是需要实现一个协议的,后面会说到. 一.已有类型的归档和解档 首先来看一个简单的例子: 1 // 2 // main.m 3 // 33_ObjectToFile 4 // 5 // Created by jiangwei on

JavaScript对象的浅拷贝与深拷贝

1.JS包含两种数据类型: 值类型(基本类型)和引用类型(对象类型) 值类型都是简单的数据段(Number.String .Boolean.Null.Undefined),引用类型是由多个值构成对象(Object .Array .Function .Data等). 我们进行变量赋值时,解析器首先要确认的就是这个值是基本类型还是引用类型. 值类型数据存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表.变量的位置和变量值的位置是重叠的,也就是说值类型的数据被存储在变量被访问的位置.

Java对象的浅拷贝和深拷贝&amp;&amp;String类型的赋值

Java中的数据类型分为基本数据类型和引用数据类型.对于这两种数据类型,在进行赋值操作.方法传参或返回值时,会有值传递和引用(地址)传递的差别. 浅拷贝(Shallow Copy): ①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象.因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,不会影响另一个对象拷贝得到的数据. ②对于数据类型是引用数据类型的成员变量,比如说成员变量是某个数组.某个类的对象等,那么浅拷贝会进行引用传递,也就是只

Python中的可变对象与不可变对象、浅拷贝与深拷贝

Python中的对象分为可变与不可变,有必要了解一下,这会影响到python对象的赋值与拷贝.而拷贝也有深浅之别. 不可变对象 简单说就是某个对象存放在内存中,这块内存中的值是不能改变的,变量指向这块内存,如果要改变变量的值,只能再开辟一块内存,放入新值,再让变量指向新开辟的内存. #定义三个变量 f=22 n=22 z=f print('f=%s,n=%s,z=%s' %(f,n,z)) print('f的地址:',id(f))#id用于获取变量内存地址 print('n的地址:',id(n)

js对象的浅拷贝与深拷贝

浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,原始(基本)类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值,如果拷贝后的对象发生变化,原对象也会发生变化.只有深拷贝才是真正地对对象的拷贝. 1.浅拷贝 默认是浅拷贝,只是将地址进行了复制,示例如下: //浅拷贝 var obj1={name:"cat"}; var obj2=obj1; o

oc学习之对象作为类的属性

对象做为类的属性 1. 一个Target中的类无法直接在另外1个Target中访问. 2. 类的属性代表什么? a. 类的属性代表这类事物具有的共同的特征 b. 类的属性代表这个类所拥有的东西. 灯: 属性: 形状 功率 价格  品牌 剩余寿命 方法: 照明. 音响: 方法: 发声音. 门: 属性: 尺寸 材料 颜色 价格 方法: 开 关 3. 类的方法代表什么? a. 代表这个类所具备的行为. 这个类所具备的功能. b. 一个类有什么方法 就去分析这个类有什么功能. 4. 属性的本质是变量.