前言:

好久没写文章了,最近先是重构IT恋、又重写IT恋中。

Sagit框架也不断的更新,调整,现在感觉已完美了了相当的多。

今天不写教程,先简单分享一下技术内容。

1:见Block必有:#define WeakSelf __weak typeof(self) this = self;

故事要从这这里说起:

当初番完这代码后,发现到处都有这个鬼东西,然后就去百度了一下,然后大意是为了:

解决双向引用导致的内存无法释放问题

简单的表述如下:

self   强引用指向=》block;

block 也强引用批向=>self;

这时候就出事了,解决的方法是,把其中一个改成弱指向。

而WeakSelf的定义,就是让block改成弱引用,这样无论self是不是强引用的指向block都无关紧要了。

当然,更精致的做法是:先预判self有没有强引用指向block,没有,就不用WeakSelf定义了。

不过,一般新手搞不明白内涵,无法做出有效的预判,所以见block就有WeakSelf也就相随相生了。

2:其它场景的双向引用:UIViewController与UIView的纠缠

首先,默认UIViewController有一个强引用指向了UIView,这是系统定义的,我们改不了:

所以,如果UIView里再出现strong或retain指回UIController,就会导致UIViewController和UIView双双无法释放问题。

这个问题,在我刚写Sagit框架时,只在意功能,没在意这些,就犯了这个错误:

错误的写法是这样的:

现在改正后的写法是这样的:

3:事情没有这么简单:UIView子控件绑定事件指向Controller

看一行Sagit的代码,关注后面的addClick:

[[[[sagit addButton:@"Login" title:@"登录" font:] width: height:] onBottom:@"pwdLine" y:] addClick:@"loginClick"];

对于事件流程关于Sagit的前面几篇有说了,这里说一下框架的流程代码:

:系统自动添加了一个UITapGestureRecognizer,并指定到一个固定的click方法;

:将方法名称和target存到自身的NSDictionary的字典中(框架为每个UIView都扩展了一个Dictionary)(就是这里造成强引用了Controller).

:事件点击时:先触发系统默认的click,然后click事件:从字典里取出方法名和target,找到SEL并动态执行。

PS:设计成动态执行的好处:可以在执行前处理一些其它事情:比如将addClick参数:loginClick改成AgeButton.click,这样可以分解参数后,去执行AgeButton上的事件

执行的代码是这样的,由于是动态执行,少不了还有一个警告:

接下来,就是怎么消灭事件里对Controller的强引用:

:找了资料,发现有个NSMapTable,是弱引用的字典,于是把NSDictionary换成它,结果:参不忍睹,界面错乱。【大概是弱引用特别容易丢失数据】 
:尝试用一个全局的第三方的字典来存,结果也悲哀了! :最后想到了一个方法,不直接存Controller,只存字符串:1和0 ,在最终执行的时候,再去找。

代码是这样的:

真难为我这么聪明,想着大功告成,运行,释放了,成功了!!!

然后又悲哀了:

然后就动不动就到main含数了,让我怎么猜?说好的全局断点呢?你咋不断呢?

搜了搜百度,想想要调度内存,那就一个蛋腾,还是靠猜吧。

后来,根据释放的顺序,和最后的关键字,大概是这样猜的:

控制器被释放了,这时候UIView还没释放,然后系统又给UIView绑字的事件发消息,结果遇到野指针,悲伤的故事发生了。

于是,我做了一个艰难的决定,在UIController的deallow中写了这样的代码:

-(void)dealloc
{
[self.view removeAllsubViews];//处理内存释放后的异常。
NSLog(@"%@ ->UIViewControlelr relase", [self class]);
}

这执行dealloc前,毕竟Controller还是活着的,这时候赶紧把UIView的东西给清了,然后,发现完美,运行起来很6!

总结:

当我很6的解决完上述问题后,就开始写文章了想分享一下了,然后写了开头,发现:

咦,好像UITableView和UITableViewCell,好像也有双向引用问题。

因为我给Cell加了个属性,指向Table,运行,果然,Shit,连Controller和父的UIView都释放了,你UITableView做为子UI居然不释放!!!!

没天理,继续折腾,然后UITableView搞释放了,又发现UITableViewCell不释放了(这个Cell通常又会是一大堆UI)。

再然后,发现Push两层回来,又挂Crash了。

现在正在全力抢救!!!解决完再来写下篇!!!

操,发现为了释放那点内存的代价,折腾起来真惨过不释放算了〜〜〜〜

讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上)的更多相关文章

  1. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug

    前言: 话说昨晚还是前晚,写了一篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上) 文章写到最后时,多了很多莫名奇妙的问题!!! 为了解决了这些莫名奇妙的问题,我又战斗了2 ...

  2. 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(下)- block中任性用self

    前言: 在处理完框架内存泄漏的问题后,见上篇:讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(中)- IOS不为人知的Bug 发现业务代码有一个地方的内存没释放,原因很也简单: ...

  3. [转] weak_ptr解决shared_ptr环状引用所引起的内存泄漏

    http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理循环引 ...

  4. weak_ptr解决shared_ptr环状引用所引起的内存泄漏[转]

    转载:http://blog.csdn.net/liuzhi1218/article/details/6993135 循环引用: 引用计数是一种便利的内存管理机制,但它有一个很大的缺点,那就是不能管理 ...

  5. 使用Xcode和Instruments调试解决iOS内存泄漏

    尽管iOS 5.0加入版本号之后ARC机制,由于相互引用关系是复杂的.内存泄漏可能仍然存在.于是,懂原理是非常重要的. 这里讲述在没有ARC的情况下,怎样使用Instruments来查找程序中的内存泄 ...

  6. android中handler使用应该注意的问题(解决由handler引起的OOM内存泄漏)

    最近,在项目过程中频繁的使用handler处理一些ui线程上的操作,以及使用handler的postdealy.然而使用过后却不对handler进行处理,进而产生了内存溢出现象,通过google,发现 ...

  7. .net 循环引用是否会造成内存泄漏

    一直想做这么一个测试,人和手的测试.类型"人"有一个属性"手",需要"手"也可以读取"人"的数据.则"手&qu ...

  8. 一步步调试解决iOS内存泄漏

      虽然iOS 5.0版本之后加入了ARC机制,由于相互引用关系比较复杂时,内存泄露还是可能存在.所以了解原理很重要. 这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄 ...

  9. 调试解决iOS内存泄漏

    这里讲述在没有ARC的情况下,如何使用Instruments来查找程序中的内存泄露,以及NSZombieEnabled设置的使用. 本文假设你已经比较熟悉Obj-C的内存管理机制. 实验的开发环境:X ...

随机推荐

  1. npm常用命令整理

    npm是一个NodeJS包管理跟分发工具,已经成为了非官方的发布node模块(包)的标准.它可以帮助我们解决代码部署上的一些问题,将开发者从繁琐的包管理工作中(版本.依赖等)解放出来,更加专注于功能上 ...

  2. Win10 之最新最简单有效安装配置adb

    今天在新买的笔记本上安装配置adb,开始觉得挺简单的事,公司win7电脑上有现成的,但实际过程中--没想的那么简单了!好了,废话少说,直接正题. 研究了好一会下,总算搞定,总结如下: 1.下载Andr ...

  3. 【NOIP2012提高组】借教室

    90分暴力解法: 用线段树,初始值为该天的教室数,每个人来申请的时候在这段区间减去借走的数,然后查询最小值是否小于0,是就输出-1,否则继续. (其实在vijos是可以直接A的,他们的评测机太快了) ...

  4. Sagit.Framework For IOS 开发框架入门开发教程2:一行代码实现引导页

    前言: 开篇比较简单:Sagit.Framework For IOS 开发框架入门开发教程1:框架下载与环境配置 第二篇教程之前写了一半,感觉不太好写,而且内容单纯介绍API,要说的很多,又枯燥乏味. ...

  5. ADC/DAC设计常见40问

    本文章是关于ADC/DAC设计经典问答,涵盖时钟占空比.共模电压.增益误差.微分相位误差.互调失真等常见问题. 1. 什么是小信号带宽(SSBW)? 小信号带宽(Small Signal Bandwi ...

  6. Map Task内部实现分析

    上篇我刚刚学习完.Spilt的过程,还算比較简单的了,接下来学习的就是Map操作的过程了,Map和Reduce一样.是整个MapReduce的重要内容,所以.这一篇,我会好好的讲讲里面的内部实现过程. ...

  7. 在IIS7上导出全部应用程序池的方法 批量域名绑定

    在IIS7+上导出全部应用程序池的方法: %windir%/system32/inetsrv/appcmd list apppool /config /xml > c:/apppools.xml ...

  8. PHP+Apache怎样监控多个port和配置多网站

    配置httpd.conf 监听多个port # Listen: Allows you to bind Apache to specific IP addresses and/or # ports, i ...

  9. Swift入门(五)——数组(Array)

    集合 集合的定义 Swift中提供了两种数据结构用于存放数据的集合,各自是数组(Array)和字典(Dictionary). 他们的主要差别在于数组中的元素由下标确定.而字典中的数据的值由数据的键(K ...

  10. 项目实战12.1—企业级监控工具应用实战-zabbix安装与基础操作

    无监控,不运维.好了,废话不多说,下面都是干货. 警告:流量党勿入,图片太多!!! 项目实战系列,总架构图 http://www.cnblogs.com/along21/p/8000812.html ...