一,retain, copy, assign区别

1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a 和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。

2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到 2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。

3. 上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。
 
4. copy是在你不希望a和b共享一块内存时会使用到。a和b各自有自己的内存。

5. atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作。在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:

if (property != newValue) {   
    [property release];   
    property = [newValue retain];   
}

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

1. 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
}
调用时:
ClassName *myName = [[ClassName alloc] init];
[classA setName:myName]; //retain count == 2
[myName release]; //retain count==1,在ClassA的dealloc中release name才能真正释放内存。

2. 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,这个对象还是没有被销毁。
上面这个例子应该这样写:
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)。

3 xcode 中的新标记 strong weak
strong 用来修饰强引用的属性;对应以前retain
 
weak 用来修饰弱引用的属性;对应以前的assign

retain,copy,assign及autorelease ,strong,weak的更多相关文章

  1. retain, copy, assign以及autorelease

    一,retain, copy, assign区别 1. 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a ...

  2. copy, retain, assign , readonly , readwrite,strong,weak,nonatomic整理

    copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议 ...

  3. COPY, RETAIN, ASSIGN , READONLY , READWRITE,STRONG,WEAK,NONATOMIC整理--转

    copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString 对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协 ...

  4. OC基础:内存(进阶):retain.copy.assign的实现原理 分类: ios学习 OC 2015-06-26 17:36 58人阅读 评论(0) 收藏

    遍历构造器的内存管理 a.遍历构造器方法内部使用autorelease释放对象 b.通过遍历构造器生成的对象.不用释放. 内存的管理总结 1.想占用某个对象的时候,要让它的引用计数器+1(retain ...

  5. retain, copy, assign区别

    1.retain, copy, assign区别 假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b.此时a 和b ...

  6. ios retain copy assign相关

    assign: 简单赋值,不更改索引计数copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 Copy其实是建立了一 ...

  7. iPhone开发教程之retain/copy/assign/setter/getter

    assign: 简单赋值,不更改索引计数 copy: 建立一个索引计数为1的对象,然后释放旧对象retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1 1. 接触过C,那么 ...

  8. assign, retain, copy, weak, strong

    一.assign, retain, copy 的区别(引用计数 RC reference count) 参考:IOS基础:retain,copy,assign及autorelease 1. 假设你用m ...

  9. strong,weak, retain, assign的区别

    strong,weak, retain, assign的区别 strong与weak是由ARC新引入的对象变量属性 xcode 4.2(ios sdk4.3和以下版本)和之前的版本使用的是retain ...

随机推荐

  1. [LintCode] Maximal Rectangle 最大矩形

    Given a 2D boolean matrix filled with False and True, find the largest rectangle containing all True ...

  2. Defining custom settings in Odoo

    Unfortunately Odoo documentation doesn’t seem to include any information about adding new configurat ...

  3. HDU1058 DP

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  4. Canvas 唯美雨落代码实现

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  5. Choose Concurrency-Friendly Data Structures

    What is a high-performance data structure? To answer that question, we're used to applying normal co ...

  6. 【iCore3 双核心板】例程二十三:LAN_HTTP实验——网页服务器

    实验指导书及代码包下载: http://pan.baidu.com/s/1getgyKr iCore3 购买链接: https://item.taobao.com/item.htm?id=524229 ...

  7. php中htmlspecialchars和htmlentiti

    Certain characters have special significance in HTML, and should be represented by HTML entities if ...

  8. javaWeb中servlet开发(3)——Servlet生命周期

    生命周期:是一个程序的存在周期,servlet由于是受容器的管理,所以容器来决定其生命周期 1.servlet生命周期 2.servlet生命周期对应的方法 3.servlet生命周期代码 publi ...

  9. [转]如何将SQL Server表驻留内存和检测

    注意这个功能在SQL2005后已经废弃,因为SQL2005会自动管理哪些表常驻内存. 将SQL Server数据表驻留内存是SQL Server提供的一项功能,在一般小型系统的开发过程中估计很少会涉及 ...

  10. Python之什么是函数

    我们知道圆的面积计算公式为: S = πr² 当我们知道半径r的值时,就可以根据公式计算出面积.假设我们需要计算3个不同大小的圆的面积: r1 = 12.34 r2 = 9.08 r3 = 73.1 ...