2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)
一 _strong修饰符
1._strong修饰符是id类型和对象类型默认的所有权修饰符。如下:
- id obj = [[NSObject alloc] init];//在没用明确变量所有权修饰符时,会被默认被_strong修饰符
- id _strong obj = [[NSObject alloc] init];//此段代码上面的是相同的。
2. 如strong这个名字所示,_strong修饰符表示对对象的强引用。持有强引用的变量在超出其作用域时会被废弃。随着强引用的失效,引用的对象会随之失效。
用一段代码来说明,如下:
- {
- id _strong obj = [[NSObject alloc] init];//自己生成并持有对象。
- /*
- 因为变量obj为强引用
- 所有自己持有对象
- */
- }
- /*
- 变量obj超出其作用域,强引用失效。
- 所以自动的释放自己所持有的对象。
- 对象的所有者不存在,所以废弃该对象。
- */
以上是自己生成且持有的对象的例子,在取得非自己生成且持有对象时也如上一样,就不在多述了。
3.下面来看一下复杂的生成并持有对象的强应用 。
- id _strong obj0 = [[NSObject alloc] init]; //对象A
- /*
- obj0持有对象A的强引用
- */
- id _strong obj1 = [[NSObject alloc] init]; //对象B
- /*
- obj1持有对象B的强引用
- */
- id _strong obj2 = nil;
- /*
- obj2不持有仍和对象
- */
- obj0 = obj1;
- /*
- obj0持有由obj1赋值的对象B的强引用
- 因为obj0被赋值,所以原先持有的对象A的强引用失效
- 对象A的所有者不存在,因此废弃该对象。
- 此时B对象的强引用变为obj0与obj1
- */
通过上面的例子可以发现_strong修饰符的变量,不仅只是在变量的作用域,在赋值上也能够正确的管理其对象的苏有着。
二 _weak修饰符
要明白_weak修饰符的作用,首先要明白_strong修饰符所带来的循环引用的问题,如下:
假设已有一个类Test继承自NSObject且存在成员变量obj也继承自NSObect。就会有以下循环引用的问题。
- {
- id test0 = [[Test alloc] init];//对象A
- //test0持有对象A的强引用
- id test1 = [[Test alloc] init];//对象B
- //test1持有对象B的强引用
- [test0 setObject:test1];
- /*
- 对象A的成员变量obj持有Test对象B的强引用
- 对象B的强引用变为test1与对象A的成员变量obj。
- */
- [test1 setObject:test0];
- /*
- 对象B的成员变量obj持有Test对象A的强引用
- 对象A的强引用变为test0与对象B的成员变量obj。
- */
- }
- /*
- 因为test0变量超出其作用域,强引用失效,
- 所以自动释放Test对象A
- 因为test1变量超出其作用域,强引用失效,
- 所以自动释放Test对象B
- 此时持有对象A的强引用的变量为:
- 对象B的成员变量obj。
- 此时持有对象B的强引用的变量为:
- 对象A的成员变量obj。
- 此时对象A与对象B都已失去作用,理应废弃他们,但是却无法废弃。
- 发生了内存泄露!
- */
循环引用容易发生内存泄露,所谓内存泄露就是指应当废弃对象的在超出其生存周期后继续存在。
像下面这种情况,虽然只有一个对象,但在该对象持有自身时,也会发生循环引用。
- id _strong obj = [[NSObject alloc] init];
- [obj setObject:obj];
2.为了避免循环引用,就要使用_weak修饰符。_weak修饰符与_strong修饰符相反,提供弱引用。弱引用不能持有对象实例。
- {
- id _strong obj0 = [[NSObject alloc] init];//自己生成并持有对象。
- id _weak obj1 = obj0;//obj1持有对象的弱引用。
- }
- /*obj0超出其作用域,强引用失效,
- 所以自动释放自己持有的对象。
- 因为对象的所有者不存在,所以废弃该对象。
- */
因为带_weak修饰符的变量(即弱引用)不持有对象,所以在超出其变量作用域时,对象即被释放。如果将之前发生循环引用的类的变量改为附有_weak修饰符的成员变量的话,就可以避免循环引用的现象。
2016 2 - 23 arc中的所有权修饰符(_strong修饰符与_weak修饰符)的更多相关文章
- block使用小结、在arc中使用block、如何防止循环引用
引言 使用block已经有一段时间了,感觉自己了解的还行,但是几天前看到CocoaChina上一个关于block的小测试主题: [小测试]你真的知道blocks在Objective-C中是怎么工作的吗 ...
- java中普通的顶级类是不能使用static关键字修饰的。只有内部类可以使用static修饰,也可以不使用staitc关键字修饰。
java中普通的顶级类是不能使用static关键字修饰的.只有内部类可以使用static修饰,也可以不使用staitc关键字修饰. java中的类可以是static吗?答案是可以.在java中我们可以 ...
- ARC中__bridge, __bridge__transfer, __bridge_retained 关系
总结于 IOS Tuturial 中 ARC两章,详细在dropbox pdf 文档. Toll-Free Bridging 当你在 Objective-C 和 Core Foundation 对象之 ...
- 如何实现ARC中weak功能?
原文链接 我们都知道ARC中weak与assign或者说unsafe_unretained最大的不同就是设置weak属性后,系统会在对象被释放后自动将指向对象的指针置为nil,而assign则会产生一 ...
- @autoreleasepool在MRC和ARC中的区别
对于@autoreleasepool {} (1)在ARC中会销毁所有在里面创建的对象,即使你用外面的Strong指针指向他 (2)在MRC中如果有外部的强指针指向,不会销毁对象,retainCoun ...
- ARC中KVO开发注意
1 在ARC 中 KVO开发 添加监听和去掉监听必需 一一匹配,不要有过的去掉监听否则会有可能导致对象无法释放. 例如,在一个viewcontroller中添加webview 并监听webview的c ...
- SQL点滴23—T-SQL中的除法
原文:SQL点滴23-T-SQL中的除法 在T-SQL中没有除法运算,但是在T-SQL中可以实现类似除法的操作Divide.一般除法操作的结果一个列来自于被除关系表,剩下的来自除关系表.这里举一个例子 ...
- ARC中block块作为属性的使用笔记
ARC中block块作为属性的使用笔记 block较难理解,根据在内存中的分布情况就分为3种类型,根据使用的情形又分为很多很多种.虽然用起来容易,但使用不当会造成内存泄露,虽然都是这么说,但你真的研究 ...
- ARC中的@autoreleasepool还有作用吗?
ARC中的@autoreleasepool还有作用吗? QUESTION For the most part with ARC (Automatic Reference Counting), we d ...
随机推荐
- HTML5Viewer中如何运行时绑定多数据源
很多报表控件提供HTML5Viewer 支持跨设备的报表系统,当然在很多情况下,一个系统可包含多个报表文件,这些报表的数据有可能均为运行时绑定数据源,那么在html5viewer中对一张报表通过重写W ...
- iframe自动高度
<script> //设置iframe自动高度 function setIframe(id){ var fn = function(){ try{ var iframe = typeof ...
- [转载]来,让我们谈一谈Normalize.css
来源 : http://segmentfault.com/a/1190000002239676 ---------------------------------------------------- ...
- React学习系列一
系列学习react 翻译地址 https://scotch.io/tutorials/learning-react-getting-started-and-concepts 我是初学者,英语也不是很好 ...
- PHP xml 转换为 array
retrun json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), tru ...
- 运行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 ...
- javascript中对象在OOP方面的一些知识(主要是prototype和__proto__相关)
在ES6的Class到来之前,先总结下个人对js中prototype属性的理解. 1.构造函数(大写函数名 this 无return) 2.原型对象(函数.prototype) 3.实例对象( ...
- java substring
str=str.substring(int beginIndex,int endIndex);中最终得到的值: beginIndex =< str的值 < endIndex
- GitHub的使用之新建与更新代码
一.新建仓储:注册GitHub后你就会有0.3G的免费空间,不过只能创建公开项目,这也满足代码分享的目的,我最喜欢的倒是它的代码展示方式,可以直接浏览你的代码,代码是经过高亮.添加行号处理过的,十分漂 ...
- Window远程连接Linux系统(CentOS7)
新开的云服务器是CentOS系统,基本操作按照腾讯云的介绍 http://www.qcloud.com/wiki/%E4%BB%8E%E6%9C%AC%E5%9C%B0Windows%E6%9C%BA ...