IOS开发复制的总结(深拷贝浅拷贝区别)

1.复制可变字符串

        NSMutableString * city = [NSMutableString stringWithString:@"北京"];
        //复制可变副本
        NSMutableString * cityCopy = [city mutableCopy];
        //修改副本
        [cityCopy replaceCharactersInRange:NSMakeRange(0, 2) withString:@"临沧"];
        //输出看到原字符串没有改变 当前的改变
        NSLog(@"原来的city是%@,现在的cityCopy是%@",city,cityCopy);

2.复制不可变字符串的可变副本

 NSString * str   [email protected]"测试的字符串";
        NSMutableString * strCopy = [str mutableCopy];
        //增加字符串
        [strCopy appendString:@"再加一段字符串"];
        NSLog(@"strCopy是是%@",strCopy);
        //为可变字符串返回一个不可变副本
        NSMutableString * cityCopy2 = [city copy];
        //由于city是不可变的下面的代码是错误的
        [cityCopy2 appendString:@"这样是错的"];

报错信息

//        2015-05-05 17:19:37.988 copyDemo[424:303] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException‘, reason: ‘Attempt to mutate immutable object with appendString:‘

//        *** First throw call stack:

总结 复制的时候返回的字符串是否可变与原来的字符串或是复制时给予的类型没有关系。主要取决于调用了copy方法还是mutableCopy方法。

3.对象拷贝

对于自定义的对象我们需要实现NSCopying和NSMutableCopying

@interface Person : NSObject
@property(nonatomic,strong)NSMutableString *name;
@property(nonatomic,assign)int age;
@end
#import "Person.h"
@interface Person()<NSCopying>
@end
@implementation Person

- (id)copyWithZone:(NSZone *)zone{
    Person * person = [[[self class] allocWithZone:zone] init];
    person.name = self.name;
    person.age = self.age;
    return person;
}
@end
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
    @autoreleasepool {

        Person * person = [Person new];
        person.name = [NSMutableString stringWithString:@"小明"];
        person.age = 20;

        Person * personCopy = [person copy];//复制副本
        personCopy.name = [NSMutableString stringWithString:@"小强"];
        personCopy.age  =23;
        NSLog(@"person的名字是%@",person.name);
        NSLog(@"person的n年龄是%d",person.age);
        NSLog(@"personCopy的名字是%@",personCopy.name);
        NSLog(@"personCopy的年龄是%d",personCopy.age);

//        2015-05-05 17:38:43.980 copyDemo[531:303] person的名字是小明
//        2015-05-05 17:38:43.981 copyDemo[531:303] person的n年龄是20
//        2015-05-05 17:38:43.981 copyDemo[531:303] personCopy的名字是小强
//        2015-05-05 17:38:43.982 copyDemo[531:303] personCopy的年龄是23
    }
    return 0;
}

4.浅拷贝

其他不变修改main函数

  Person * person = [Person new];
        person.name = [NSMutableString stringWithString:@"小明"];
        person.age = 20;
        Person * personCopy = [person copy];//复制副本
        [personCopy.name replaceCharactersInRange:NSMakeRange(0,2) withString:@"变了嘛"];
        personCopy.age  =23;
        NSLog(@"person的名字是%@",person.name);
        NSLog(@"person的n年龄是%d",person.age);
        NSLog(@"personCopy的名字是%@",personCopy.name);
        NSLog(@"personCopy的年龄是%d",personCopy.age);

打印出来的是

2015-05-05 17:54:05.347 copyDemo[563:303] person的名字是变了嘛

2015-05-05 17:54:05.349 copyDemo[563:303] person的n年龄是20

2015-05-05 17:54:05.350 copyDemo[563:303] personCopy的名字是变了嘛

2015-05-05 17:54:05.350 copyDemo[563:303] personCopy的年龄是23

一开始我也很迷惑。差距只有一句代码而已。不过还是有差别的。

原因就在

    person.name = self.name;
    person.age = self.age;

name是一个指针变量,存放的只是字符串地而已。所以说修改了拷贝的name,原来的name也会发生改变,使用personCopy.name = [NSMutableString stringWithString:@"小强"];这句代码的话其实是直接重新赋值,指向了另外一个字符串指针,所以拷贝的对象修改了。原来的并没有改变。但是并不代表拷贝的时候不指向一个字符串。只是后来被修改了。

5.深拷贝

将copyWithZone方法里面的修改

    person.name = [self.name mutableCopy];
    person.age = self.age;

这样就实现了深复制。

但是一般情况下,深复制难度比较大。尤其是有很多指针的时候,Fundation一般都是浅复制。

6.setetr方法的复制

修改如下代码

@property(nonatomic,copy)NSMutableString *name;

修改main

        Person * person = [Person new];
        person.name = [NSMutableString stringWithString:@"小明"];
        //下面这行代码会报错的。
        [person.name appendString:@"会报错了"];

name的属性使用了copy指示符的话其实相当于setNmame方法里面

- (void)setName(NSString *)name{
name = [name copy];
}

是对参数的一个不可变拷贝

时间: 2024-08-17 00:39:22

IOS开发复制的总结(深拷贝浅拷贝区别)的相关文章

iOS开发-Alpha,Hidden与Opaque区别

UIView中的这三个属性用的比较多,尤其是Alpha和Opaque之间有的时候不是很好分别,稍微整理下: Alpha(不透明度) alpha是不透明度,属性为浮点类型的值,取值范围从0到1.0,表示从完全透明到完全不透明,其特性有当前UIView的alpha值会被其所有subview继承.alpha值会影响到UIView跟其所有subview,alpha具有动画效果.当alpha为0时,跟hidden为YES时效果一样,但是alpha主要用于实现隐藏的动画效果,在动画块中将hidden设置为Y

iOS开发new与alloc/init的区别

概括来说,new和alloc/init在功能上几乎是一致的,分配内存并完成初始化.差别在于,采用new的方式只能采用默认的init方法完成初始化,采用alloc的方式可以用其他定制的初始化方法. AD: 英文详解:http://macresearch.org/difference-between-alloc-init-and-new 1.在实际开发中很少会用到new,一般创建对象咱们看到的全是[[className alloc] init] 但是并不意味着你不会接触到new,在一些代码中还是会看

iOS开发中frame与bounds的区别

闲话不多说,先上两张图,大伙们就已经明白了: 显示出来的效果是这样子滴:  总结: 要理清这两者的区别,最主要的要理解一下几个概念:frame可以理解为可视的范围,而bounds可以理解为可视范围内的内容位置.在默认的情况下,frame与bounds的原点,也就是x与y轴是重合. 父视图中的frame与bounds,子视图中的frame与bounds,据我的理解,决定子视图的位置要两个条件,那就是父视图中的bounds与子视图中的frame:而子视图中的bounds与子子视图的frame决定着子

iOS开发--复制到剪贴板

代码是很简单,用的少,所以容易忘. UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; pasteboard.string = @"复制的内容";

iOS开发----操作系统----进程和线程的区别

进程和线程的主要差别在于它们是不同的操作系统资源管理方式. 进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径. 线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉, 所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些. 但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程. 一个程序至少有一个进程,一个进程至少有一个线程. 线程的划分尺度小于进程

【iOS开发】@property跟成员变量区别

@property在xcode 4.5之前只是单纯的告诉编译器,“我在后面实现了对那个变量的setter和getter方法,你放心吧”,但是如果你不写synthesize配合的话就会出错.synthesize才是代替setter和getter的关键部分. @synthesize在xcode4.5之前是配合@property使用,帮助你隐式了实现了一个setter和getter.如果你没有在interface里声明变量,它会帮你隐式的创建一个已下划线开头的同名变量,比如@synthesize my

iOS开发-View中frame和bounds区别

开发中调整View的时候的经常会遇到frame和bounds,刚开始看的时候不是很清楚,不过看了一下官方文档,frame是确定视图在父视图中的位置,和本身的大小,bounds确定可以确定子视图在当前视图中的位置,还可以改变View的大小,如果bounds确定大小,那么View的视图优先选择的bounds中的宽高.Center的位置是相对于父坐标系中的定位.苹果官方给了一张图片供参考: 如果还不是很清晰,可以参考一下frame和bounds的中代码: -(CGRect)frame{ return

iOS开发----网络部分----HTTPS和HTTP的区别

一.https协议需要到ca申请证书,一般免费证书很少,需要交费.  二.http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议.  三.http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443.  四.http的连接很简单,是无状态的:HTTPS协议是由SSL+HTTP协议构建的可进行加密传输.身份认证的网络协议,比http协议安全.

IOS中复制对象的用法及深拷贝和浅拷贝详解

亲爱的网友,我这里有套课程想和大家分享,如果对这个课程有兴趣的,可以加我的QQ2059055336和我联系. 课程内容简介 我们软件是基于移动设备的.所以我们必然的选择了安卓作为我们的开发工具.课程中,我们将简要的介绍Android的基本概念,然后进行我们的实战开发.在开发中,大家讲学习到基本的组件,适配UI,数据的存储,多线程下载,开机广播,闹钟提醒,短信发送等实际项目开发中碰到的有用的知识点.通过课程学习,让大家能够掌握Android软件开发的流程,注意点,及优化.帮助大家迅速的掌握Andr