一 _strong修饰符

1._strong修饰符是id类型和对象类型默认的所有权修饰符。如下:

  1. id obj = [[NSObject alloc] init];//在没用明确变量所有权修饰符时,会被默认被_strong修饰符
  2.  
  3. id _strong obj = [[NSObject alloc] init];//此段代码上面的是相同的。

2. 如strong这个名字所示,_strong修饰符表示对对象的强引用。持有强引用的变量在超出其作用域时会被废弃。随着强引用的失效,引用的对象会随之失效。

用一段代码来说明,如下:

  1. {
  2. id _strong obj = [[NSObject alloc] init];//自己生成并持有对象。
  3. /*
  4. 因为变量obj为强引用
  5. 所有自己持有对象
  6. */
  7. }
  8. /*
  9. 变量obj超出其作用域,强引用失效。
  10. 所以自动的释放自己所持有的对象。
  11. 对象的所有者不存在,所以废弃该对象。
  12. */

以上是自己生成且持有的对象的例子,在取得非自己生成且持有对象时也如上一样,就不在多述了。

3.下面来看一下复杂的生成并持有对象的强应用 。

  1. id _strong obj0 = [[NSObject alloc] init]; //对象A
  2. /*
  3. obj0持有对象A的强引用
  4. */
  5.  
  6. id _strong obj1 = [[NSObject alloc] init]; //对象B
  7. /*
  8. obj1持有对象B的强引用
  9. */
  10. id _strong obj2 = nil
  11. /*
  12. obj2不持有仍和对象
  13. */
  14.  
  15. obj0 = obj1;
  16. /*
  17. obj0持有由obj1赋值的对象B的强引用
  18. 因为obj0被赋值,所以原先持有的对象A的强引用失效
  19. 对象A的所有者不存在,因此废弃该对象。
  20.  
  21. 此时B对象的强引用变为obj0与obj1
  22. */

通过上面的例子可以发现_strong修饰符的变量,不仅只是在变量的作用域,在赋值上也能够正确的管理其对象的苏有着。

二 _weak修饰符

要明白_weak修饰符的作用,首先要明白_strong修饰符所带来的循环引用的问题,如下:

假设已有一个类Test继承自NSObject且存在成员变量obj也继承自NSObect。就会有以下循环引用的问题。

  1. {
  2. id test0 = [[Test alloc] init];//对象A
  3. //test0持有对象A的强引用
  4. id test1 = [[Test alloc] init];//对象B
  5. //test1持有对象B的强引用
  6. [test0 setObject:test1];
  7. /*
  8. 对象A的成员变量obj持有Test对象B的强引用
  9. 对象B的强引用变为test1与对象A的成员变量obj。
  10. */
  11. [test1 setObject:test0];
  12. /*
  13. 对象B的成员变量obj持有Test对象A的强引用
  14. 对象A的强引用变为test0与对象B的成员变量obj。
  15. */
  16. }
  17. /*
  18. 因为test0变量超出其作用域,强引用失效,
  19. 所以自动释放Test对象A
  20.  
  21. 因为test1变量超出其作用域,强引用失效,
  22. 所以自动释放Test对象B
  23.  
  24. 此时持有对象A的强引用的变量为:
  25. 对象B的成员变量obj。
  26.  
  27. 此时持有对象B的强引用的变量为:
  28. 对象A的成员变量obj。
  29.  
  30. 此时对象A与对象B都已失去作用,理应废弃他们,但是却无法废弃。
  31. 发生了内存泄露!
  32. */

循环引用容易发生内存泄露,所谓内存泄露就是指应当废弃对象的在超出其生存周期后继续存在。

像下面这种情况,虽然只有一个对象,但在该对象持有自身时,也会发生循环引用。

  1. id _strong obj = [[NSObject alloc] init];
  2. [obj setObject:obj];

2.为了避免循环引用,就要使用_weak修饰符。_weak修饰符与_strong修饰符相反,提供弱引用。弱引用不能持有对象实例。

  1. {
  2.  
  3. id _strong obj0 = [[NSObject alloc] init];//自己生成并持有对象。
  4.  
  5. id _weak obj1 = obj0;//obj1持有对象的弱引用。
  6. }
  7. /*obj0超出其作用域,强引用失效,
  8. 所以自动释放自己持有的对象。
  9. 因为对象的所有者不存在,所以废弃该对象。
  10. */

因为带_weak修饰符的变量(即弱引用)不持有对象,所以在超出其变量作用域时,对象即被释放。如果将之前发生循环引用的类的变量改为附有_weak修饰符的成员变量的话,就可以避免循环引用的现象。

2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)的更多相关文章

  1. block使用小结、在arc中使用block、如何防止循环引用

    引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...

  2. java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。

    java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...

  3. ARC中__bridge, __bridge__transfer, __bridge_retained 关系

    总结于 IOS Tuturial 中 ARC两章,详细在dropbox pdf 文档. Toll-Free Bridging 当你在 Objective-C 和 Core Foundation 对象之 ...

  4. 如何实现ARC中weak功能?

    原文链接 我们都知道ARC中weak与assign或者说unsafe_unretained最大的不同就是设置weak属性后,系统会在对象被释放后自动将指向对象的指针置为nil,而assign则会产生一 ...

  5. @autoreleasepool在MRC和ARC中的区别

    对于@autoreleasepool {} (1)在ARC中会销毁所有在里面创建的对象,即使你用外面的Strong指针指向他 (2)在MRC中如果有外部的强指针指向,不会销毁对象,retainCoun ...

  6. ARC中KVO开发注意

    1 在ARC 中 KVO开发 添加监听和去掉监听必需 一一匹配,不要有过的去掉监听否则会有可能导致对象无法释放. 例如,在一个viewcontroller中添加webview 并监听webview的c ...

  7. SQL点滴23—T-SQL中的除法

    原文:SQL点滴23-T-SQL中的除法 在T-SQL中没有除法运算,但是在T-SQL中可以实现类似除法的操作Divide.一般除法操作的结果一个列来自于被除关系表,剩下的来自除关系表.这里举一个例子 ...

  8. ARC中block块作为属性的使用笔记

    ARC中block块作为属性的使用笔记 block较难理解,根据在内存中的分布情况就分为3种类型,根据使用的情形又分为很多很多种.虽然用起来容易,但使用不当会造成内存泄露,虽然都是这么说,但你真的研究 ...

  9. ARC中的@autoreleasepool还有作用吗?

    ARC中的@autoreleasepool还有作用吗? QUESTION For the most part with ARC (Automatic Reference Counting), we d ...

随机推荐

  1. HTML5Viewer中如何运行时绑定多数据源

    很多报表控件提供HTML5Viewer 支持跨设备的报表系统,当然在很多情况下,一个系统可包含多个报表文件,这些报表的数据有可能均为运行时绑定数据源,那么在html5viewer中对一张报表通过重写W ...

  2. iframe自动高度

    <script> //设置iframe自动高度 function setIframe(id){ var fn = function(){ try{ var iframe = typeof ...

  3. [转载]来,让我们谈一谈Normalize.css

    来源 : http://segmentfault.com/a/1190000002239676 ---------------------------------------------------- ...

  4. React学习系列一

    系列学习react 翻译地址 https://scotch.io/tutorials/learning-react-getting-started-and-concepts 我是初学者,英语也不是很好 ...

  5. PHP xml 转换为 array

    retrun json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), tru ...

  6. 运行DbVisualizer报the java_home environment viariable does not point to a working 32-bit JDK OR JRE错误

    报这个错误的根本原因就是DbVisualizer和JDK的版本不一致,那么知道原因,修改起来就方便了,要么修改DbVisualizer的版本,要么修改JDK的版本. 1.JDK7 64位 那么就在Db ...

  7. javascript中对象在OOP方面的一些知识(主要是prototype和__proto__相关)

    在ES6的Class到来之前,先总结下个人对js中prototype属性的理解. 1.构造函数(大写函数名  this 无return)   2.原型对象(函数.prototype)  3.实例对象( ...

  8. java substring

    str=str.substring(int beginIndex,int endIndex);中最终得到的值: beginIndex =< str的值 < endIndex

  9. GitHub的使用之新建与更新代码

    一.新建仓储:注册GitHub后你就会有0.3G的免费空间,不过只能创建公开项目,这也满足代码分享的目的,我最喜欢的倒是它的代码展示方式,可以直接浏览你的代码,代码是经过高亮.添加行号处理过的,十分漂 ...

  10. Window远程连接Linux系统(CentOS7)

    新开的云服务器是CentOS系统,基本操作按照腾讯云的介绍 http://www.qcloud.com/wiki/%E4%BB%8E%E6%9C%AC%E5%9C%B0Windows%E6%9C%BA ...