//自定义类对象实现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. jquery的getjson与jsonp

    仔细的学习jquery的getjson的用法. http://www.cnblogs.com/leejersey/p/3750232.html http://www.jb51.net/article/ ...

  2. git的理解

    1.对git的分支怎么理解. git的本地,git的跟踪,如果我们的本地的命令行进入某个分支的话,我们的本地对应的文件夹就显示某个,然后我们的ide打开的就是那个分支 2.git的在线视频教学 htt ...

  3. SDRAM基础知识

    SDRAM知识普及 在学习SDRAM之前,必须先了解"SDRAM"这个概念性的东西,并有感性的认识转变到一种理性的认识,所谓理性的认识就是实质性的东西…….不多说,相信你已经迫不急 ...

  4. 34-nl 简明笔记

    为文本文件添加行号 nl [options] files 参数 files是nl需要为其添加行号的文本文件路径名,如果有多个文件,则nl会把多个文件合在一起编号,并输出到标准输出上 选项 -b     ...

  5. linux中级-JAVA企业级应用TOMCAT实战

    1. Tomcat简介 Tomcat是Apache软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun和其他一些公司及个人共 ...

  6. [转] java中int,char,string三种类型的相互转换

    原文地址:http://blog.csdn.net/lisa0220/article/details/6649707 如何将字串 String 转换成整数 int? int i = Integer.v ...

  7. poj1144 求不同割点的个数

    Network Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 11914   Accepted: 5519 Descript ...

  8. Mybatis + SpringMVC + Maven实现分页查询

    使用Mybatis + Maven + SpringMVC 运行时,突然被需要分页查询的功能给难住了 这里推荐采用的插件是PageHelper这个插件,使用起来十分方便.该插件支持以下数据库: Ora ...

  9. Tomcat安装

    第一步,下载: 直接上下载地址:http://tomcat.apache.org/download-70.cgi 直接下载如下选中即可: 第二步,安装: 然后解压(这里我是放在下载里),再进入bin目 ...

  10. Segment-Based stereo matching

    首先代码实现是根据"Segment-Based Stereo Matching Using Belief Propogation and Self-Adapting Dissimilarit ...