copy的原理:

执行<NSCopying>协议,类中必须实现copyWithZone:方法响应的copy消息。

copy消息将发送copyWithZone:这个消息给你的类,它的参数是nil。

copyWithZone:返回一个不可改变的copy

  1. *MyPoint.h*/
  2. #import <Foundation/Foundation.h>
  3. @interface MyPoint : NSObject<NSCopying>//继承超类
  4. {
  5. int x;
  6. int y;
  7. };
  8. //set方法
  9. -(void) setMyPoint:(int)x andY:(int)y;
  10. //get方法
  11. -(int) getX;
  12. -(int) getY;
  13. @end
  1. /*MyPoint.m*/
  2. #import "MyPoint.h"
  3. @implementation MyPoint
  4. -(void) setMyPoint:(int)_x andY:(int)_y
  5. {
  6. //要对传进来的x和y进行判断
  7. if(_x<0)
  8. {
  9. x = 1;
  10. }
  11. if(_y<0)
  12. {
  13. y = 1;
  14. }
  15. x = _x;
  16. y = _y;
  17. }
  18. -(int) getX
  19. {
  20. return x;
  21. }
  22. -(int) getY
  23. {
  24. return y;
  25. }
  26. //copy
  27. /*
  28. zone参数处理不同的你alloc出来的内存区域,如果你写的应用程序alloc了大量的内存,并且你又想优化你的内存区域。
  29. 你可以给copywithzone传值,调用allocwithzone来alloc内存:这个方法可以在指定的区域alloc内存
  30. */
  31. -(id) copyWithZone:(NSZone *)zone //创建一个复制的接收器,储存zone
  32. {
  33. MyPoint *newPoint = [[MyPoint allocWithZone:zone]init];
  34. [newPoint setMyPoint:x andY:y];
  35. return newPoint;
  36. }
  37. /*
  38. NSZone 是苹果系统对内存分配和释放的优化方式。
  39. NSZone不是一个对象;它是一个C结构,用于纪录关于内存处理(管理)一系列对象的信息
  40. 在这里它处理了zone这个传进来的对象的信息
  41. */
  42. @end
  1. #import <Foundation/Foundation.h>
  2. #import "MyPoint.h"
  3. int main (int argc, const char * argv[])
  4. {
  5. MyPoint *point1 = [[MyPoint alloc]init];//创建myPoint对象,alloc是分配内存空间,init是初始化
  6. [point1 setMyPoint:2 andY:3];//调用对象point1的方法
  7. NSLog(@"x = %i",[point1 getX]);//[point1 getX]调用get方法
  8. NSLog(@"y = %i",[point1 getY]);
  9. MyPoint *point2 = [point1 copy];//实现复制构造
  10. [point2 setMyPoint:5 andY:5];
  11. NSLog(@"x = %i",[point2 getX]);
  12. NSLog(@"y = %i",[point2 getY]);
  13. [point1 release];// release 是释放分配的内存空间
  14. [point2 release];
  15. return 0;
  16. }
  17. ios拷贝小议

     

    1.copy vs mutableCopy

    copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.

    mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.

    2.copy vc retain

    retain,引用计数+1,内存地址赋值给左值.

    copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.

    举例:

        NSString* a = [NSString stringWithFormat:@"%@",@"this is a"];
    
        NSString* b = [a copy];
    
        NSString* bb = [a retain];
    
        NSString* cc = [a mutableCopy];//实际上cc应该是NSMutableString类型
    
        NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);
    
    //输出3,3,3,1
        NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];
    
        NSString* b = [a copy];//不可变的b
    
        NSString* bb = [a retain];//实际类型是NSMutableString的bb
    
        NSString* cc = [a mutableCopy];//同上
    
        NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);
    
    //输出2,1,2,1

    3.一些问题

    通过上面2点,思考下面的问题

    我们通常如果这样定义一个变量

    @property(nonatomic,copy)  NSMutableString* mString;

    然后这样使用

    @synthesize mString;
    
    NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];
    
    self.mString = a;
    
    [mString insertString:@"m-" atIndex:0];

    能通过么?当然不能,赋值后的mString是NSString类型的,不可变.如果需要可以改变就需要自己定义属性函数.

    -(void)setMString:(NSMutableString *)m
    
    {
    
        mString = [m mutableCopy];
    
    }
    
    -(NSMutableString *)mString
    
    {
    
        return mString;
    
    }

    (当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)

    4.NSCopying NSMutableCopying NSCopyObjective()

    NSCopying就是复制一个对象

    NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响

    (其实上面着两个完全看你怎么写啦)

    NSCopyObject(self,0,zone)就是简单的赋值=

    (在涉及到ns对象的时候,NSCopyObject不建议使用)

    注意看下面一个例子:

    @interface ClassB : NSObject <NSCopying>{
    NSString* stringB;
    } @property(nonatomic,copy) NSString* stringB; @end
    -(id)copyWithZone:(NSZone *)zone
    
    {
    
        ClassB *b = NSCopyObject(self, 0, zone);
    
    // 使用NSCopyObject时的正确赋值方法,因为没有涉及到原来的内存指针什么事
    
        b->stringB = @"what";
    
    // 看看被注释的这个错误方法,由于setter方法的特性,原来的stringB指向的内存的retainCount减一
    
    // 而由于NSCopyObject的特性,两者又是指向同一个地址的,所以,原类中stirngB指向的地址已经释放了,之后你dealloc中在释放一次?!.就出错啦
    
    //    b.stringB = @"what";
    
        return b;
    
    }
    ios拷贝小议
    2011-10-13 10:44:45     我来说两句      
    收藏    我要投稿

    1.copy vs mutableCopy

    copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.

    mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.

    2.copy vc retain

    retain,引用计数+1,内存地址赋值给左值.

    copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.

    举例:

    NSString* a = [NSString stringWithFormat:@"%@",@"this is a"];    NSString* b = [a copy];    NSString* bb = [a retain];    NSString* cc = [a mutableCopy];//实际上cc应该是NSMutableString类型    NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);//输出3,3,3,1    NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];    NSString* b = [a copy];//不可变的b    NSString* bb = [a retain];//实际类型是NSMutableString的bb    NSString* cc = [a mutableCopy];//同上    NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);//输出2,1,2,1
    3.一些问题

    通过上面2点,思考下面的问题

    我们通常如果这样定义一个变量

    @property(nonatomic,copy)  NSMutableString* mString;然后这样使用

    @synthesize mString;NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];self.mString = a;[mString insertString:@"m-" atIndex:0];
    能通过么?当然不能,赋值后的mString是NSString类型的,不可变.如果需要可以改变就需要自己定义属性函数.

    -(void)setMString:(NSMutableString *)m{    mString = [m mutableCopy];}-(NSMutableString *)mString{    return mString;}(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)

    4.NSCopying NSMutableCopying NSCopyObjective()

    NSCopying就是复制一个对象

    NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响

    (其实上面着两个完全看你怎么写啦)

    NSCopyObject(self,0,zone)就是简单的赋值=

    (在涉及到ns对象的时候,NSCopyObject不建议使用)

    注意看下面一个例子:

    @interface ClassB : NSObject <NSCopying>{    NSString* stringB;}@property(nonatomic,copy) NSString* stringB;@end-(id)copyWithZone:(NSZone *)zone{    ClassB *b = NSCopyObject(self, 0, zone);// 使用NSCopyObject时的正确赋值方法,因为没有涉及到原来的内存指针什么事    b->stringB = @"what";// 看看被注释的这个错误方法,由于setter方法的特性,原来的stringB指向的内存的retainCount减一// 而由于NSCopyObject的特性,两者又是指向同一个地址的,所以,原类中stirngB指向的地址已经释放了,之后你dealloc中在释放一次?!.就出错啦//    b.stringB = @"what";    return b;}

Objective-c之NSCopying的更多相关文章

  1. Automake

    Automake是用来根据Makefile.am生成Makefile.in的工具 标准Makefile目标 'make all' Build programs, libraries, document ...

  2. iOS开发——新特性OC篇&Objective新特性

    Objective新特性 Overview 自 WWDC 2015 推出和开源 Swift 2.0 后,大家对 Swift 的热情又一次高涨起来,在羡慕创业公司的朋友们大谈 Swift 新特性的同时, ...

  3. iOS开发核心语言Objective C —— 全部知识点总结

    本分享是面向有意向从事iOS开发的伙伴及苹果产品的发烧友,亦或是已经从事了iOS的开发人员,想进一步提升者.假设您对iOS开发有极高的兴趣,能够与我一起探讨iOS开发.一起学习,共同进步.假设您是零基 ...

  4. Objective C中的ARC的修饰符的使用---- 学习笔记九

    #import <Foundation/Foundation.h> @interface Test : NSObject /** * 默认的就是__strong,这里只是做示范,实际使用时 ...

  5. Objective-O Runtime 运行时初体验

    Objective-C语言是一门动态语言,它将很多静态语言在编译和链接时期做的事放到了运行时来处理.这种动态语言的优势在于:我们写代码时更具灵活性,如我们可以把消息转发给我们想要的对象,或者随意交换一 ...

  6. Objective的字符串拼接 似乎没有Swift方便,但也可以制做一些较为方便的写法

    NSString *str1 = @"字符串1"; NSString *str2 = @"字符串2"; //在同样条件下,Objective的字符串拼接 往往只 ...

  7. [转] 从 C 到 Objective C 入门1

    转自: http://blog.liuhongwei.cn/iphone/objective-c/ 进军iPhone开发,最大的难点之一就是怪异的Objective C语法了.不过,了解之后才发现,原 ...

  8. Objective C运行时(runtime)

    #import <objc/runtime.h> void setBeingRemoved(id __self, SEL _cmd) { NSLog(@"------------ ...

  9. Objective C ARC 使用及原理

    手把手教你ARC ,里面介绍了ARC的一些特性, 还有将非ARC工程转换成ARC工程的方法 ARC 苹果官方文档 下面用我自己的话介绍一下ARC,并将看文档过程中的疑问和答案写下来.下面有些是翻译,但 ...

  10. Objective -C学习笔记 之copy(复制)

    //自定义类对象实现copy需要遵守copy协议(否则程序崩溃),实现必须实现的协议方法,里面的代码就决定了你的copy是深是浅 #import <Foundation/Foundation.h ...

随机推荐

  1. disconf实践(二)

    因为有些系统的配置文件会随着业务更改,如某些控制开关,当大批量集群时,按照上一篇文章的配置就不够啦,需要做到热加载. 研究了一下,还好,比较简单,只要替换上一篇文章第4步的配置文件(spring-di ...

  2. Javascript UserAgent 获取平台及浏览器信息

    公司最近要做一套类似于百度统计的功能,于是收集整理了其中根据UserAgent获取客户端平台及浏览器信息的资料,不仅仅试用于Javascript,其他语言也可以参考相应正则进行改进.当然,肯定有不足的 ...

  3. percona-MYSQLGUI监控

    1.https://www.percona.com/blog/2016/05/26/monitoring-with-percona-app-for-grafana/ http://pmmdemo.pe ...

  4. warning:This application is modifying the autolayout engine from a background thread

    警告提示:This application is modifying the autolayout engine from a background thread, which can lead to ...

  5. 对象-关系映射ORM(Object Relational Mapping)(转)

    ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现 Hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.java).映射文件(*.hbm.xml)和数据库配置文件 ...

  6. JQ 让光标在文本框最末尾

    function setFocus() { //文本末尾获得焦点 var obj = event.srcElement; var txt = obj.createTextRange(); txt.mo ...

  7. php中调用其他系统http接口的方法说明

    使用函数: file_get_contents($url); 传入接口url及其参数:如 $url="http://192.168.1.1/test.jsp?id=1&type=2& ...

  8. OpenCart 之registry功用

    1. “Registry”设计模式 在OpenCart中,Registry是整个系统的信息中枢. Registry是一个单例(Singleton),在index.php起始页面中, 首先作为构造函数参 ...

  9. sql查询过程中 update,insert,delete可视化收影响行数

    insert into test_tb output inserted.id,inserted.data values('c'),('d') delete from test_tb output de ...

  10. PHP 进行统一邮箱登陆的代理实现(swoole)

    在工作的过程中,经常会有很多应用有发邮件的需求,这个时候需要在每个应用中配置smtp服务器.一旦公司调整了smtp服务器的配置,比如修改了密码等,这个时候对于维护的人员来说要逐一修改应用中smtp的配 ...