copy语法的目的:改变副本的时候,不会影响到源对象;

深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

拷贝有下面两个方法实现拷贝:

- (id)copy;
- (id)mutableCopy;

对象要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例:

1.不可变字符串调用copy实现拷(浅拷贝)

NSString *string = [[NSString alloc] initWithFormat:@"abcde"];
// copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
// 源对象计数器会+1
// 在浅拷贝情况下,copy其实就相当于retain
NSString *str = [string copy];

2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)

NSString *string = [[NSString alloc] initWithFormat:@"abcd"];
// 产生了一个新的对象,计数器为1。源对象的计数器不变。
NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
// str和string不是相同对象
// NSLog(@"%i", str == string);//0
[str appendString:@" abcd"];//修改str不影响string
NSLog(@"string:%@", string);
NSLog(@"str:%@", str);

3.可变字符串调用copy实现拷贝(深拷贝)

NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSString *str = [string copy];

4.可变字符串的MutableCopy(深拷贝)

NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSMutableString *str = [string mutableCopy];
[str appendString:@"1234"];//修改新对象不影响原对象
NSLog(@"str:%@", str);
NSLog(@"string:%@", string);

5.拷贝自定义对象,下面以Student对象为例

a.Student要实现copy,必须实现<NSCopying>协议

b.实现<NSCopying>协议的方法:

- (id)copyWithZone:(NSZone *)zone

Student.h文件

@interface Student : NSObject <NSCopying>  

// copy代表set方法会release旧对象、copy新对象
// 修改外面的变量,并不会影响到内部的成员变量
// 建议:NSString一般用copy策略,其他对象一般用retain
@property (nonatomic, copy) NSString *name; + (id)studentWithName:(NSString *)name; @end

Student.m文件

#import "Student.h"  

@implementation Student  

+ (id)studentWithName:(NSString *)name {
// 这里最好写[self class]
Student *stu = [[[[self class] alloc] init] autorelease];
stu.name = name; return stu;
} - (void)dealloc {
[_name release]; [super dealloc];
} #pragma mark description方法内部不能打印self,不然会造成死循环
- (NSString *)description {
return [NSString stringWithFormat:@"[name=%@]", _name];
} #pragma mark copying协议的方法
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
Student *copy = [[[self class] allocWithZone:zone] init]; // 拷贝名字给副本对象
copy.name = self.name; return copy;
} @end

拷贝Student

Student *stu1 = [Student studentWithName:@"stu1"];  

Student *stu2 = [stu1 copy];
stu2.name = @"stu2"; NSLog(@"stu1:%@", stu1);
NSLog(@"stu2:%@", stu2); [stu2 release];

小结:

建议:NSString一般用copy策略,其他对象一般用retain;

只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;

iOS 深拷贝、浅拷贝、自定义对象拷贝简介的更多相关文章

  1. Python 关于拷贝(copy)汇总(列表拷贝 // 字典拷贝 // 自定义对象拷贝)

    1.列表拷贝 引用是指保存的值为对象的地址.在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些.下面举个例子: 问题描述:已知一个列表, ...

  2. [iOS]深拷贝/浅拷贝区别

    来点鸡汤: // 所谓拷贝 就是在原有的对象的基础上产生一个新的副本对象.有两点原则: //   1. 改变原对象的属性和行为不会影响副本对象 //   2. 改变副本对象的属性和行为不会影响原对象 ...

  3. IOS 如何持久化自定义对象 2014-08-01 01:38

    如果持久话自定义对象 那么这个对象一定要遵循 NSCoding 协议 并实现编解码:然后再将编解码后的数据 NSKeyedArchiver 到NSData中   @interface NSKeyAnd ...

  4. iOS深拷贝浅拷贝

    浅拷贝:浅拷贝并不拷贝对象本身,只是对指向对象的指针进行拷贝深拷贝:直接拷贝对象到内存中一块区域,然后把新对象的指针指向这块内存 在iOS中并不是所有对象都支持Copy和MutableCopy,遵循N ...

  5. ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍(转)

    copy语法的目的:改变副本的时候,不会影响到源对象: 深拷贝:内容拷贝,会产生新的对象.新对象计数器置为1,源对象计数器不变. 浅拷贝:指针拷贝,不会产生新的对象.源对象计数器+1. 拷贝有下面两个 ...

  6. ObjectiveC中的赋值,对象拷贝,浅拷贝与深拷贝

    在开发过程中我们经常会遇到对象拷贝的问题,下面我们分别讨论赋值操作.对象拷贝.以及浅拷贝(Shallow copy)与深拷贝(Deep copy)的区别与各自的实现方式. 一.不同对象的赋值操作 Ob ...

  7. iOS 自定义对象及子类及模型套模型的拷贝、归档存储的通用代码

    一.runtime实现通用copy 如果自定义类的子类,模型套模型你真的会copy吗,小心有坑. copy需要自定义类继承NSCopying协议 #import <objc/runtime.h& ...

  8. IOS的浅拷贝和深拷贝

    什么是深拷贝和浅拷贝 浅拷贝:就是指针的复制,拷贝的指针跟原指针指向内存中的同一个位置的对象.至于对象的引用计数值是否+1,就是看拷贝的指针赋给给的变量是Strong类型的,还是week类型的. 如果 ...

  9. C++拷贝构造函数(深拷贝&浅拷贝)

    对于普通类型的对象来说,它们之间的复制是很简单的,例如: int a=88; int b=a; 而类对象与普通对象不同,类对象内部结构一般较为复杂,存在各种成员变量.下面看一个类对象拷贝的简单例子. ...

随机推荐

  1. Java 5/Java 6/Java7/Java 8新特性收集

    前言: Java 8对应的JDK版本为JDK8,而官网下载回来安装的时候,文件夹上写的是JDK1.8,同一个意思.(而这个版本命名也是有规律的,以此类推) 一.Java 5 1.https://seg ...

  2. Linux下的搜索命令grep(转)

    一.简介 grep(global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具, ...

  3. tcp-time-wait-state

    https://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux

  4. linux 每天备份mysql数据

    原文:http://www.open-open.com/code/view/1433587311890 前言: 如果你的数据库文件较大,可能备份的时候需要占用很多服务器资源,所以站长要尽量选择访客最少 ...

  5. Linux的SOCKET编程详解(转)

    Linux的SOCKET编程详解 1. 网络中进程之间如何通信 进 程通信的概念最初来源于单机系统.由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进 程之间既互不干扰又协调一致工作,操作系 ...

  6. Android四大组件的生命周期

    介绍生命周期之前,先提一下任务的概念 任务其实就是activity 的栈它由一个或多个Activity组成的共同完成一个完整的用户体验, 换句话说任务就是” 应用程序” (可以是一个也可以是多个,比如 ...

  7. Python——正則表達式(2)

    本文译自官方文档:Regular Expression HOWTO 參考文章:Python--正則表達式(1) 全文下载 :Python正則表達式基础 ======================== ...

  8. 不是技术牛人,如何拿到国内IT巨头的Offer--转

    http://blog.csdn.net/lsldd/article/details/13506263 不久前,byvoid面阿里星计划的面试结果截图泄漏,引起无数IT屌丝的羡慕敬仰.看看这些牛人,N ...

  9. Intel MIC

    http://en.wikipedia.org/wiki/Intel_MIC Intel MIC From Wikipedia, the free encyclopedia     Intel Man ...

  10. openwrt procd 运行的一些log

    void procd_inittab(void) { #define LINE_LEN 128 FILE *fp = fopen(tab, "r"); struct init_ac ...