retain, copy, assign区别

一、retain, copy, assign区别

  • 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a 和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块 内存的时候会引起程序crash掉。
  • 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到 2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候, 代表该内存不再被任何指针所引用,系统可以把它直接释放掉。
  • 上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。
  • copy是在你不希望a和b共享一块内存时会使用到。a和b各自有自己的内存。
  • atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错 误的结果。加了atomic,setter函数会变成下面这样:
 if (property != newValue) {
    [property release];
    property = [newValue retain];
}

二、深入理解一下(包括autorelease)

  • retain之后count加一。alloc之后count就是1,release就会调用dealloc销毁这个对象。

    如果 retain,需要release两次。通常在method中把参数赋给成员变量时需要retain。

    例如:

    ClassA有 setName这个方法:

    -(void)setName:(ClassName *) inputName
    {
       name = inputName;
       [name retain]; //此处retian,等同于[inputName retain],count等于2
    }

    调用时:

    OC ClassName *myName = [[ClassName alloc] init]; [classA setName:myName]; //retain count == 2 [myName release]; //retain count==1,在ClassA的dealloc中release name才能真正释放内存。

    • autorelease 更加tricky,而且很容易被它的名字迷惑。我在这里要强调一下:autorelease不是garbage collection,完全不同于Java或者.Net中的GC。

      autorelease和作用域没有任何关系!

      autorelease 原理:

      a.先建立一个autorelease pool

      b.对象从这个autorelease pool里面生成。

      c.对象生成 之后调用autorelease函数,这个函数的作用仅仅是在autorelease pool中做个标记,让pool记得将来release一下这个对象。

      d.程序结束时,pool本身也需要rerlease, 此时pool会把每一个标记为autorelease的对象release一次。如果某个对象此时retain count大于1,这个对象还是没有被销毁。

      上面这个例子应该这样写:

      OC ClassName *myName = [[[ClassName alloc] init] autorelease];//标记为autorelease [classA setName:myName]; //retain count == 2 [myName release]; //retain count==1,注意,在ClassA的dealloc中不能release name,否则release pool时会release这个retain count为0的对象,这是不对的。

      记住一点:如果这个对象是你alloc或者new出来 的,你就需要调用release。如果使用autorelease,那么仅在发生过retain的时候release一次(让retain count始终为1)。

原文地址:https://www.cnblogs.com/CH520/p/9189265.html

时间: 2024-08-03 23:05:39

retain, copy, assign区别的相关文章

retain,copy,assign及autorelease ,strong,weak

一,retain, copy, assign区别 1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a 和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉. 2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference countin

OC基础:内存(进阶):retain.copy.assign的实现原理

遍历构造器的内存管理 a.遍历构造器方法内部使用autorelease释放对象 b.通过遍历构造器生成的对象.不用释放. 内存的管理总结 1.想占用某个对象的时候,要让它的引用计数器+1(retain操作) 2.当不想再占用某个对象的时候,要让它的引用计数器-1(release操作) 3.谁alloc谁release,遍历构造器使用autorelease 另:当一个属性遵循了协议的时候(该属性就是代理),这时使用内存组的assign修饰. 多态:父类指针 指向 子类对象 没有继承就没有多态 父类

关于内存方面,retain,copy,assign

内存管理机制 引用计数:因为OC中不存在垃圾回收机制,所以才根据引用计数回收机制.当引用计数为0时,销毁空间.也就是说,根据引用计数来确定一个对象是否释放. 可以改变引用计数的操作:allco retain release copy dealloc 便利构造器 自动释放池: 每次对象调用autorelease 方法时(obj-c中的正式说法应该是:给对象发送autorelease消息),对象的引用计数并不是真正变化,而是向pool中添加一条记录,记下对象的这种要求.最后当pool发送drain

strong retain copy对于 nsstring,nsmutablestring的区别

#import "ViewController.h" @interface ViewController ()@property (retain,nonatomic) NSString *myRetainStr;@property (copy, nonatomic) NSString *myCopyStr;@property (strong, nonatomic) NSString *myStrongStr;@end @implementation ViewController - (

IOS开发 strong,weak,retain,assign,copy nomatic 等的区别与作用

strong,weak,retain,assign,copy nomatic 等的区别 copy与retain:1.copy其实是建立了一个相同的对象,而retain不是:2.copy是内容拷贝,retain是指针拷贝:  3.copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".4.copy的情况:NSString *newPt = [pt copy];此时会在

iOS中assign,copy,retain之间的区别以及weak和strong的区别

@property (nonatomic, assign) NSString *title; 什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Reference Counting). copy: 建立一个索引计数为1的对象,然后释放旧对象 retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 weak 和strong的区别: (weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会

iOS 开发 property,strong,weak,retain,assign,copy,nomatic 的区别及使用

1:ARC环境下,strong代替retain.weak代替assign,xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain和assign,是不支持ARC的.xcode 4.3(ios5和以上版本)之后就有了ARC,并且开始使用 strong与weak 2:weak的作用:在ARC环境下,所有指向这个对象的weak指针都将被置为nil.这个T特性很有用,相信很多开发者都被指针指向已释放的对象所造成的EXC_BAD_ACCESS困扰过,使用ARC以后,不论是str

copy,assign,strong,retain,weak,readonly,nonatomic的区别

copy与retain:1.copy其实是建立了一个相同的对象,而retain不是:2.copy是内容拷贝,retain是指针拷贝:  3.copy是内容的拷贝 ,对于像NSString,的确是这样,但是如果copy的是一个NSArray呢?这时只是copy了指向array中相对应元素的指针.这便是所谓的"浅复制".4.copy的情况:NSString *newPt = [pt copy];此时会在堆上重新开辟一段内存存放@"abc" 比如0X1122 内容为@&q

assign retain 和copy的区别

assign 对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等 等. 此标记说明设置器直接进?行赋值,这也是默认值.在使?用垃圾收集的应?用程序中,如 果你要?一个属性使?用assign,且这个类符合NSCopying协 议,你就要明确指出这个标 记,?而不是简单地使?用默认值,否则的话,你将得到?一个编译警告.这再次向编译器说 明你确实需要赋值,即使它是可拷?贝的. retain对其他NSObject和其?子类对参数进?行