//自定义类对象实现copy需要遵守copy协议(否则程序崩溃),实现必须实现的协议方法,里面的代码就决定了你的copy是深是浅
 #import <Foundation/Foundation.h>
#import "Student.h" //接口部分
// @interface Student : NSObject//<NSCopying/*copy协议*/,NSCoding/*归档协议*/>
//
//@property(nonatomic,copy)NSString *name;
//@property(nonatomic,assign)int Age;
//
//@end int main(int argc, const char * argv[])
{
@autoreleasepool
{
Student *student = [[Student alloc] init];
student.name = @"liuguan";
student.Age = ;
NSLog(@"%@",student);
Student *student1 = [student copy];//深复制
//协议实现方式
/***************************
//如果直接return self,则是浅拷贝,如果使用alloc,则是深拷贝
- (id)copyWithZone:(NSZone *)zone
{
Student *stu = [Student allocWithZone:zone];
// Student *stu = [[[[self class] allocWithZone:zone]init]autorelease];// ARC
// stu.name = self.name;
// stu.Age = self.Age;
stu.name = [self.name copy];
stu.Age = self.Age;
NSLog(@"%p***%p",stu.name,self.name);//0x100002078***0x100002078地址一致(浅copy)
return stu;
}//相当于stu的地址等于self的地址,但是这个地址是新开辟的,所以跟copy接收者就没关系了
***************************/ //Student *student1 = [student copy];//浅复制 // 协议实现方式
/*************************
//- (id)copyWithZone:(NSZone *)zone
//{
// return self;//直接相等
//}//相当于self的地址直接等于copy接受者的地址
相当于 Student *student1 = student ;
***************************/
student1.name = @"wangxinag";
NSLog(@"%@",student1);
NSLog(@"%@",student);
}
return ;
}

在这里首先提及的就是定义属性是用的属性列表中的copy

@property(nonatomic,copy)NSString *name;

在这里我定义了一个Person类,此处不再陈述

下面是代码

Person *p = [[Person alloc] init];

NSMutableString *s = [[NSMutableString alloc] initWithFormat:@"123"];

p.name = s;   //此时,name的值为@"123"

NSLog(@"**%@",p.name);

[s appendString:@"world"];

NSLog(@"%@",p.name);

NSLog(@"%p---%p",s,p.name);

输出结果:

**123

123

0x100206e00---0x100206cf0

可以看出可变字符串的值赋给了属性name,但是地址变化了,在第一次输出123后边我又对s进行了重新赋值为world,但是并未影响到p.name的值,这也就验证了地址确实不同了。其实它内部是通过

- (void)setName:(NSMutableString *)name

{

if(_name != name){          //判断是否需要重新赋值

[_name release];        //释放旧引用,计数器-1

_name = [name copy];   //重新赋值,使用copy********就是这里*********

}

}

进行了深复制。因为s是可变数组,所以copy之后会开辟一个新的地址空间。假如s是不可变数组,那么就会进行浅复制

假如把代码改成:

Person *p = [[Person alloc] init];

NSString *s = @"123";

p.name = s;   //此时,name的值为@"123"

NSLog(@"%@",p.name);

NSLog(@"%p---%p",s,p.name);

输出结果:

123

0x100001068---0x100001068

地址是一样的,说明进行了浅复制

总结:

copy:浅拷贝:不产生新的对象,直接指向原有对象(地址数据相同,虽然指针的名字不同)
    拷贝出的结果是不可变对象,跟其接受类型没有关系,跟其传入类型也没有关系
mutableCopy:深拷贝:产生新的对象,其内容是原有对象的内容,地址变了
    拷贝的结果是可变对象,跟其传入的类型没有关系,但是会受其接收类型的影响
copy:被复制着是可变,则为深,否则为浅

NSString *s2 = [s1 copy];//八种情况中(s1:mutableString/String;s2:mutableString/String;copy/mutableCopy),只有s1为不可变和利用copy方法  同时满足时为浅复制,其余为深复制

//当使用NSCopy复制一个不可变对象时,其行为是浅复制,其余情况都是深拷贝
//当使用NSMutablecopy时,是深拷贝

那么为什么浅复制地址不变呢?

        当被copy者类型是字符串常量时(就是不可变字符串),系统会为我们优化,声明了多个字符串,
        但是都是常量,且内容相等,那么系统就只为我们申请一块空间。
赋值过程:输入数据→寄存器处理→开辟内存→写入数据。一次深复制,可以得到被复制对象指针,并进行一次赋值操作。

Objective -C学习笔记 之copy(复制)的更多相关文章

  1. OGG学习笔记02-单向复制配置实例

    OGG学习笔记02-单向复制配置实例 实验环境: 源端:192.168.1.30,Oracle 10.2.0.5 单实例 目标端:192.168.1.31,Oracle 10.2.0.5 单实例 1. ...

  2. OGG学习笔记03-单向复制简单故障处理

    OGG学习笔记03-单向复制简单故障处理 环境:参考:OGG学习笔记02-单向复制配置实例 实验目的:了解OGG简单故障的基本处理思路. 1. 故障现象 故障现象:启动OGG源端的extract进程, ...

  3. Java程序猿JavaScript学习笔记(2——复制和继承财产)

    计划和完成在这个例子中,音符的以下序列: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaSc ...

  4. MySQL学习笔记十七:复制特性

    一.MySQL的复制是将主数据库(master)的数据复制到从(slave)数据库上,专业一点讲就是将主数据库DDL和DML操作的二进制日志传到从库上,然后从库对这些二进制日志进行重做,使得主数据库与 ...

  5. Docker学习笔记之Copy on Write机制

    0x00 概述 Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新 ...

  6. Linux学习笔记--cp命令(复制)

    cp:英文名copy,复制的意思. 1. 命令格式: cp [选项] 源文件或文件夹 目标文件或文件夹 cp [选项] 源文件1 源文件2 源文件3 ... 目标文件夹 2. 经常使用选项: &quo ...

  7. 学习笔记--C#深复制和浅复制

    参考博客:http://www.cnblogs.com/nliao/archive/2012/11/18/2776114.html 例子网上都有很多,我也就不列了. 其实很久以前就明白了这两者的区别, ...

  8. MongoDB学习笔记八:复制

    [主从复制]最基本的复制方式就是建立一个主节点和一个或多个从节点,每个从节点要知道主节点的地址.运行mongod --master启动主服务器.运行mongod --slave --source ma ...

  9. Objective -C学习笔记之字典

    //字典:(关键字 值) // NSArray *array = [NSArray array];//空数组 // NSDictionary *dictionary = [NSDictionary d ...

随机推荐

  1. word2vec使用说明补充(google工具包)

    [本文转自http://ir.dlut.edu.cn/NewsShow.aspx?ID=253,感谢原作者] word2vec是一个将单词转换成向量形式的工具.可以把对文本内容的处理简化为向量空间中的 ...

  2. SqlServer——批量插入数据

    像Major表里面批量插入数据演示: 代码如下: Declare @I int Set @I= Begin Tran InsertData: Insert into Major values(@I,' ...

  3. iOS 监听textfield的输入(转)

    1:首先 [textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEvent ...

  4. Day Seven(Beta)

    站立式会议 站立式会议内容总结 331 今天: 1)阅读html 5+文档 未来走h5路线 2)restful,未来开发接口 3)h5+demo运行 4)get 代码:a||(a=as); 5)js ...

  5. SVN常见图标的含义

    项目视图   The Package Explorer view - 已忽略版本控制的文件.可以通过Window → Preferences → Team → Ignored Resources.来忽 ...

  6. MyEclipse10连接数据库

    连接oracle数据库 DB窗口>>右键:新建

  7. 【转】HTTP协议详解

    原文地址:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html 一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则 ...

  8. ubuntu15.10下搭建cordova+ionic开发环境

    安装jdk 在命令下输入java如果没有安装会提示该命令包含于openjdk软件包 sudo apt-get install openjdk然后按下tab会列出openjdk开头的软件包 我这里就选择 ...

  9. bzoj3998: [TJOI2015]弦论

    SAM小裸题qwq #include <iostream> #include <cstdio> #include <cmath> #include <cstr ...

  10. Unity 移动端触摸屏操作

    Unity 触屏操作 当将Unity游戏运行到IOS或Android设备上时,桌面系统的鼠标左键可以自动变为手机屏幕上的触屏操作,但如多点触屏等操作却是无法利用鼠标操作进行的.Unity的Input类 ...