zoukankan      html  css  js  c++  java
  • iOS开发知识点:理解assign,copy,retain变strong

    一、.h和.m文件的变化说明

    1.对于.h头文件,主要是将属性定义由retain变为strong 

    1. @property (retain, nonatomic)  

    变为

      

    1. @property (strong, nonatomic)  


    2.在ARC之前,我们经常在.m中使用分类拓展来增加私有的property

    1. @interface MJViewController ()  
    2. @property (nonatomic, retain) NSArray *data;  
    3. @end  

    这 样做主要是简化实例对象的手动内存管理,让property的setter方法自动管理原来对象的释放,以及新对象的retain。但是有了ARC,这样 的代码就不再需要了。一般来说,仅仅为了简化内存管理,是不再需要使用property的,虽然你仍然可以这样做,但直接使用实例变量是更好的选择。只有 那些属于public的实例变量,才应该定义为property

    我们可以直接在.m类实现中定义private实例变量,不必写分类拓展了:

    1. @implementation MJViewController {  
    2.     NSArray *data;  
    3. }  

    不过还是要在viewDidUnload方法中将data设置为nil,因为data是个strong指针,当不再使用一个对象时,应该设置为nil

    1. - (void)viewDidUnload {  
    2.     [super viewDidUnload];  
    3.     data = nil;  
    4. }  


    二、IBOutlet

    在ARC中,所有IBOutlet属性都推荐使用weak, 这些view对象已经属于View Controller的view hierarchy,不需要再次定义为strong。因此,这些定义为weak的IBOutlet属性都不需要在IBOutlet中设置为nil

      

    三、@property的修饰符小结

    • strong : 该属性值对应 __strong 关键字,即该属性所声明的变量将成为对象的持有者,等同于"retain"
    • weak : 该属性对应 __weak 关键字,与 __weak 定义的变量一致,该属性所声明的变量将没有对象的所有权,并且当对象被释放之后,对象将被自动赋值nil,记住IBOutlet应该使用weak
    • unsafe_unretained : 等效于__unsafe_unretaind关键字声明的变量,等同于之前的"assign",iOS 5之前的系统用该属性代替 weak 来使用
    • copy : 和之前的copy一样,复制一个对象并创建strong关联
    • assign : 对象不能使用assign,但原始类型(BOOL、int、float)仍然可以使用

    举个例子:

        NSString *houseOfMM = [[NSString alloc] initWithString:'装梵几的三室两厅']; 

    上面一段代码会执行以下两个动作: 
    1 在堆上分配一段内存用来存储@' 装梵几的三室两厅 ' ,比如:内存地址为 0X1111  内容为 ' 装梵几的三室两厅' , 
    2 在栈上分配一段内存用来存储 houseForWife ,比如:地址为 0XAAAA  内容自然为 0X1111   


    下面分别看下(assign,retain,copy): 
    1.assign的情况: NSString  * myHouse  = [ houseOfMM   assign ]; 
    此时 myHouse 和 houseOfMM 完全相同,地址都是 0XAAAA  ,内容为 0X1111  ,即 myHouse 只是 houseOfMM 的别名,对任何一个操作就等于对另一个操作。因此 retainCount 不需要增加.(同进同出,关系好,一把钥匙,给我拿着) 
    2.retain的情况: NSString  *  myHouse  = [ houseOfMM   retain ]; 
    此时 myHouse 的地址不再为 0XAAAA ,可能为 0XAABB ,但是内容依然为 0X1111 .因此 myHouse 和 houseOfMM 都可以管理' 装梵几的三室两厅 '所在的内存。因此  retainCount 需要增加1.(有些独立,各自进出,两把钥匙) 
    3.copy的情况: NSString  *  myHouse  = [ houseOfMM   copy ]; 

    此时会在堆上重新开辟一段内存存放@'装梵几的三室两厅',比如0X1122,内容为@'装梵几的三室两厅',同时会在栈上为myHouse分配空间,比如地址:0XAACC,内容为0X1122,因此retainCount增加1供myHouse来管理0X1122这段内存.(两套@'装梵几的三室两厅',条件好,分居了,房子一人一套,所以钥匙一人一把。)



    什么时候用assign,当然是破房子,简装的房子拉
    基础类型(简单类型,原子类型):NSInteger,CGPoint,CGFloat,C数据类型(int,float,double,char等)


    什么时候用copy
    含有可深拷贝的mutable子类的类,如NSArray,NSSet,NSDictionary,NSData的,NSCharacterSet,NSIndexSet,NSString
    (可深度拷贝的房子)
    但是NSMutableArray这样的不可以,Mutable的不能用copy,不然初始化会有问题。切记

    什么时候用retain
    其他NSObject和其子类对象好嘛 (大多数)


    ARC中的strong相当于非ARC中的retain,ARC来了以后多搞一把钥匙就strong了啦。

    原文:http://wenku.baidu.com/view/ab6ed804bed5b9f3f90f1c7d.html

    浅拷贝和深拷贝 

    浅拷贝

    浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。如:

    
    
    1
    2
    char* str = (char*)malloc(100);
    char* str2 = str;

    浅拷贝只是对对象的简单拷贝,让几个对象共用一片内存,当内存销毁的时候,指向这片内存的几个指针需要重新定义才可以使用,要不然会成为野指针。

    iOS 里面的浅拷贝:

    在 iOS 里面, 使用retain 关键字进行引用计数,就是一种更加保险的浅拷贝。他既让几个指针共用同一片内存空间,又可以在release 由于计数的存在,不会轻易的销毁内存,达到更加简单使用的目的。

    深拷贝:

    深拷贝是指拷贝对象的具体内容,而内存地址是自主分配的,拷贝结束之后,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉。

    copy 与 retain 的区别:

    copy 是创建一个新对象,retain 是创建一个指针,引用对象计数加一。 copy属性标识两个对象内容相同,新的对象retain count为1, 与旧有对象引用计数无关,旧有对象没有变化。copy减少对象对上下文的依赖。

    iOS里的深拷贝:

    iOS提供了copy和mutableCopy方法,顾名思义,copy就是复制了一个imutable的对象,而mutableCopy就是复制了一个mutable的对象。以下将举几个例子来说明。
    这里指的是NSString, NSNumber等等一类的对象。

    1 NSString *string = @”dddd";
    2 NSString *stringCopy = [string copy];
    3 NSMutableString *stringDCopy = [string mutableCopy];
    4 [stringMCopy appendString:@"!!"];
    查看内存可以发现,string和stringCopy指向的是同一块内存区域(weak reference),引用计数没有发生改变。而stringMCopy则是我们所说的真正意义上的复制,系统为其分配了新内存,是两个独立的字符串内容是一样的。

    拷贝构造:

    当然在 ios 中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying协议的类可以发送copy消息,遵守NSMutableCopying协议的类才可以发送mutableCopy消息。

    假如发送了一个没有遵守上诉两协议而发送copy或者 mutableCopy,那么就会发生异常。但是默认的ios类并没有遵守这两个协议。如果想自定义一下copy 那么就必须遵守NSCopying,并且实现 copyWithZone: 方法,如果想自定义一下mutableCopy 那么就必须遵守NSMutableCopying,并且实现 mutableCopyWithZone: 方法。

    如果是我们定义的对象,那么我们自己要实现NSCopying , NSMutableCopying这样就能调用copy和mutablecopy了。举个例子:

     
    1 @interface MyObj : NSObject<NSCopying, NSMutableCopying>{
    2     NSMutableString *_name;
    3     NSString * _imutableStr ;
    4     int _age;
    5 }     
    6 @property (nonatomic, retain) NSMutableString *name;
    7 @property (nonatomic, retain) NSString *imutableStr;
    8 @property (nonatomic) int age;

    copy拷贝构造:
    1 - (id)copyWithZone:(NSZone *)zone{
    2     MyObj *copy = [[[self class] allocWithZone :zone] init];
    3     copy->name = [_name copy];
    4     copy->imutableStr = [_imutableStr copy];
    5     copy->age = age;
    6     return copy;
    7 }

    mutableCopy拷贝构造:

    1 - (id)mutableCopyWithZone:(NSZone *)zone{
    2     MyObj *copy = NSCopyObject(self, 0, zone);
    3     copy->name = [_name mutableCopy];
    4     copy->age = age;
    5     return copy;
    6 }

    有空的话翻译一下好嘛:

    http://clang.llvm.org/docs/AutomaticReferenceCounting.html

    https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocProperties.html

    http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html


    先看这个 :

    http://blog.csdn.net/favormm/article/details/7023322

    http://www.crifan.com/object_c_property_setter_assign_retain_copy_weak_strong/

    http://www.crifan.com/object_c_property_setter_assign_retain_copy_weak_strong/

  • 相关阅读:
    [原]OpenSSL SSL连接初始化部分解析
    [转]C++日志系统log4cxx使用总结
    js打字效果
    抓取网页Email地址
    jQuery语法总结及注意事项
    Reporting Services中参数说明(因为在框架中要在新的窗口打开报表,所以这理主要是rc:LinkTarget)
    jQuery性能优化指南
    安装文件制作总结
    alert弹出层(待完善……)
    我的tab页面,Jquery方便扩展
  • 原文地址:https://www.cnblogs.com/A--G/p/4619607.html
Copyright © 2011-2022 走看看