//自定义类对象实现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. [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...

  2. [BZOJ1263][SCOI2006]整数划分(数学+高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1263 分析:数学老师上课讲过啦= =,就是尽可能3越多越好.然后就写个高精度就行了.

  3. 自然数从1到n之间,有多少个数字含有1

        问题明确而简单.for循环肯定是不好的.       用递推方法:       定义h(n)=从1到9999.....9999  ( n 个 9)之间含有1的数字的个数.定义f(n)为n位数中 ...

  4. 删除root子目录,如何恢复子目录配置文件

    手贱,一不小心rm -rf 问题描述:删除/root/子目录文件(含隐藏配置文件)shell变成-bash-4.2#,如何恢复原貌 解决方法: root用户进入,自己配置相关文件:mkdir /roo ...

  5. Map集合的应用及其遍历方式

    ---> HashMap :底层基于哈希表      存储原理也使用哈希表来存放的:            往HashMap添加了元素 ,首先会调用键的hashCode方法 获得一个哈希值,然后 ...

  6. 转 漫谈linux文件IO

    在Linux 开发中,有几个关系到性能的东西,技术人员非常关注:进程,CPU,MEM,网络IO,磁盘IO.本篇文件打算详细全面,深入浅出.剖析文件IO的细节.从多个角度探索如何提高IO性能.本文尽量用 ...

  7. Jenkins的maven工程打包的时候怎么指定不同环境的配置文件

    http://outofmemory.cn/code-snippet/6643/maven-profile-define-enviroment-package 在打包的时候我们添加上 这里我们指定配置 ...

  8. Elasticsearch: Indexing SQL databases. The easy way

    Elasticsearchis a great search engine, flexible, fast and fun. So how can I get started with it? Thi ...

  9. ETL利器Kettle实战应用解析系列一【Kettle使用介绍】

    本系列文章主要索引如下: 一.ETL利器Kettle实战应用解析系列一[Kettle使用介绍] 二.ETL利器Kettle实战应用解析系列二 [应用场景和实战DEMO下载] 三.ETL利器Kettle ...

  10. java-首字母大小写

    /** * 首字母小写 * * @param str * @return */ public static String toLowerCaseFirstChar(String s) { if (Ch ...