[HMLY]10.深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用
前言
在上篇中,仔细分析了一下Block的实现原理以及__block捕获外部变量的原理。然而实际使用Block过程中,还是会遇到一些问题,比如Retain Circle的问题。
目录
- 1.Retain Circle的由来
- 2.__weak、__strong的实现原理
- 3.weakSelf、strongSelf的用途
- 4.@weakify、@strongify实现原理
一. Retain Circle的由来
循环引用的问题相信大家都很理解了,这里还是简单的提一下。
当A对象里面强引用了B对象,B对象又强引用了A对象,这样两者的retainCount值一直都无法为0,于是内存始终无法释放,导致内存泄露。所谓的内存泄露就是本应该释放的对象,在其生命周期结束之后依旧存在。

这是2个对象之间的,相应的,这种循环还能存在于3,4……个对象之间,只要相互形成环,就会导致Retain Cicle的问题。
当然也存在自身引用自身的,当一个对象内部的一个obj,强引用的自身,也会导致循环引用的问题出现。常见的就是block里面引用的问题。

二.__weak、__strong的实现原理
在ARC环境下,id类型和对象类型和C语言其他类型不同,类型前必须加上所有权的修饰符。
所有权修饰符总共有4种:
1.__strong修饰符
2.__weak修饰符
3.__unsafe_unretained修饰符
4.__autoreleasing修饰符
一般我们如果不写,默认的修饰符是__strong。
要想弄清楚__strong,__weak的实现原理,我们就需要研究研究clang(LLVM编译器)和objc4 Objective-C runtime库了。
关于clang有一份关于ARC详细的文档,有兴趣的可以仔细研究一下文档里面的说明和例子,很有帮助。
以下的讲解,也会来自于上述文档中的函数说明。
1.__strong的实现原理
(1)对象持有自己
首先我们先来看看生成的对象持有自己的情况,利用alloc/new/copy/mutableCopy生成对象。
当我们声明了一个__strong对象
{
id __strong obj = [[NSObject alloc] init];
}
LLVM编译器会把上述代码转换成下面的样子
id __attribute__((objc_ownership(strong))) obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));
相应的会调用
id obj = objc_msgSend(NSObject, @selector(alloc));
objc_msgSend(obj,selector(init));
objc_release(obj);
上述这些方法都好理解。在ARC有效的时候就会自动插入release代码,在作用域结束的时候自动释放。
[HMLY]10.深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用的更多相关文章
- 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用(上)
深入研究Block捕获外部变量和__block实现原理 前言 在上篇中,仔细分析了一下Block的实现原理以及__block捕获外部变量的原理.然而实际使用Block过程中,还是会遇到一些问题,比如R ...
- 深入研究Block用weakSelf、strongSelf、@weakify、@strongify解决循环引用(下)
深入研究Block捕获外部变量和__block实现原理 EOCNetworkFetcher.h typedef void (^EOCNetworkFetcherCompletionHandler)(N ...
- @weakify, @strongify ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify
首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...
- ObjC的Block中使用weakSelf/strongSelf @weakify/@strongify
首先要说说什么时候使用weakSelf和strongSelf. 下面引用一篇博客<到底什么时候才需要在ObjC的Block中使用weakSelf/strongSelf>的内容: Objec ...
- block为什么用copy以及如何解决循环引用
在完成项目期间,不可避免的会使用到block,因为block有着比delegate和notification可读性更高,而且看起来代码也会很简洁.于是在目前的项目中大量的使用block. 之前给大家介 ...
- [HMLY]10.iOS中block的基础用法
本文简介 本章不会对Block做过多的实现研究.只是讲解基本的用法.纯粹基础知识.结合实际项目怎么去做举例.Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等.用过GCD就知道 ...
- ios block常见的错误(二)——循环引用
这篇博文继续block的常见错误——循环引用. 循环引用是很多初学者不能察觉的,其产生的原因,是block中的代码会对对象进行强引用. 读者请阅读示例代码1,并思考示例代码1所创建的对象能否被正常销毁 ...
- ios 使用block中使用self可能产生的循环引用
在block中调用 self,那么就会引起循环引用问题,那么这是为什么呢? 为什么self会对block进行强引用呢???? 这里推荐一篇关于block的专业文章,http://blog.csdn.n ...
- iOS中block的使用、实现底层、循环引用、存储位置
一.整体介绍 定义:C语言的匿名函数,
随机推荐
- Rails当你运行一个数据库回滚错误:ActiveRecord::IrreversibleMigration exception
最近rails3.2在更改数据库表字段,然后要回滚取消,但在运行rake db:rollback命令,错误: rake aborted! An error has occurred, all late ...
- JQUERY 插件开发——MENU(导航菜单)
JQUERY 插件开发——MENU(导航菜单) 故事背景:由于最近太忙了,已经很久没有写jquery插件开发系列了.但是凭着自己对这方面的爱好,我还是抽了一些时间来过一下插件瘾的.今天的主题是导航菜单 ...
- python网络爬虫进入(一)——简单的博客爬行动物
最近.对于图形微信公众号.互联网收集和阅读一些疯狂的-depth新闻和有趣,发人深思文本注释,并选择最佳的发表论文数篇了.但看着它的感觉是一个麻烦的一人死亡.寻找一个简单的解决方案的方法,看看你是否可 ...
- C#编程实践–帮老婆计算产假方案
摘要 今天中午午休时,和老婆聊天,老婆还过几天就要请产假了,她在网上问我让我帮她数一下该怎么请假最划算,老婆是个会过日子的人,面对此种要求我当然义不容辞,不过想到这个问题我的第一反应是:这个怎么可以用 ...
- CSS3中文手册基础知识
CSS3手册是学习CSS3的最佳文档,不管是自己写博客,还是买书,手册少不了.今天我给大家介绍一些CSS3有哪些分类及其使用. 具体参考:http://caibaojian.com/css3/ 上来进 ...
- C#动态表达式计算
C#动态表达式计算 应该有不少人开发过程中遇到过这样的需求,我们直接看图说话: 如上图所示,其中Entity为实体类,其中包括五个属性,该五个属性的值分别来自于数据库查询结果: 用户通过可视化界面进行 ...
- JQuery UI Layout Plug-in布局
端]使用JQuery UI Layout Plug-in布局 引言 使用JQuery UI Layout Plug-in布局框架实现快速布局,用起来还是挺方便的,稍微研究了一下,就能上手,关于该布 ...
- NUnit单元测试资料汇总
NUnit单元测试资料汇总 从安装到配置 首先到官网http://www.nunit.org/下载如下图的资料,安装NUnit-2.6.1.msi包. 然后挂在VS2010外部工具这个地方来使用,工具 ...
- Binder机制,从Java到C (3. ServiceManager in Java)
上一篇 Binder机制,从Java到C (2. IPC in System Service :AMS) 中提到 Application是通过ServiceManager找到了AMS 的servic ...
- ioc和aop
IOC容器的基本原理 ioc又称为控制反转.或者依赖注入.为什么叫控制反转呢? 可以这样来看.软件开发中会有很多的类,这些类在一起完成复杂的功能.这些类之间存在了耦合的关系.就如同很多的齿轮,啮合 ...