zoukankan      html  css  js  c++  java
  • Objective-c之NSCopying

     

    Objective-c之NSCopying

     
     

    copy的原理:

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

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

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

    1. *MyPoint.h*/  
    2. #import <Foundation/Foundation.h>  
    3.   
    4.   
    5. @interface MyPoint : NSObject<NSCopying>//继承超类  
    6. {  
    7.     int x;  
    8.     int y;  
    9. };  
    10. //set方法  
    11. -(void) setMyPoint:(int)x andY:(int)y;  
    12. //get方法  
    13. -(int) getX;  
    14. -(int) getY;  
    15.   
    16. @end  


     

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

       

  • 相关阅读:
    Support依赖库大全
    反射调用泛型
    会爬行的小乌龟
    改进版——使用了双缓冲技术
    启动运行发现窗体不能最大化,添加
    添加图层
    实现放大,缩小,漫游,复位等功能
    从上一个项目中我得到的反思
    ​Error -4075: File not found. An error occurred merging module <MODULENAME> for feature <FEATURENAME>.
    总结—angularjs项目
  • 原文地址:https://www.cnblogs.com/iOS-mt/p/4119663.html
Copyright © 2011-2022 走看看