前言:

好久没写文章了,最近先是重构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:40] width:450 height:80] onBottom:@"pwdLine" y:149] addClick:@"loginClick"];

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

1:系统自动添加了一个UITapGestureRecognizer,并指定到一个固定的click方法;2:将方法名称和target存到自身的NSDictionary的字典中(框架为每个UIView都扩展了一个Dictionary)(就是这里造成强引用了Controller).3:事件点击时:先触发系统默认的click,然后click事件:从字典里取出方法名和target,找到SEL并动态执行。PS:设计成动态执行的好处:可以在执行前处理一些其它事情:比如将addClick参数:loginClick改成AgeButton.click,这样可以分解参数后,去执行AgeButton上的事件

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

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

1:找了资料,发现有个NSMapTable,是弱引用的字典,于是把NSDictionary换成它,结果:参不忍睹,界面错乱。【大概是弱引用特别容易丢失数据】 2:尝试用一个全局的第三方的字典来存,结果也悲哀了!3:最后想到了一个方法,不直接存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了。

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

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

转载于:https://www.cnblogs.com/cyq1162/p/8195220.html

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

  1. 解决出现线程未关闭 , 造成内存泄漏问题

    解决出现线程未关闭 , 造成内存泄漏问题 16-Feb-2022 16:38:24.978 警告 [main] org.apache.catalina.loader.WebappClassLoader ...

  2. 怎么解决 数据丢失的问题_ThreadLocal中内存泄漏和数据丢失问题的问题浅析及解决方案...

    特点: 依托于线程的生命周期而存在,贯穿于整个线程,解决了线程前后值传递的问题. 一次存入,只要线程不结束都可以获取到 不具有多线程之间共用数值的特性,只存在于单个线程内,主子线程之间不会出现值传递. ...

  3. 内存泄漏的原因及解决办法_浅谈 JS 内存泄漏问题

    什么是内存泄漏? 程序的运行需要内存.只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存. 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存.否则,内存占用越来越高 ...

  4. iOS循环引用问题集合、内存泄漏、僵尸对象、代码静态分析

    内存泄漏:https://my.oschina.net/llfk/blog/1031291 内存泄漏监测自动化:http://www.cocoachina.com/articles/18490 fac ...

  5. 为什么view的setOnClickListener引用Activity不会内存泄漏

    学就完事 本文:https://www.jianshu.com/p/4b3aad1b8dba 文章目录 前言 什么是内存泄露 答题 兴趣 OnClickListener在View中的引用位置 View ...

  6. Nacos本地进行了远程配置而远程未配置相关信息而导致应用报内存泄漏问题的异常

    今天在用Nacos时突然出了这么一个问题: 意思是:[main]o.a.c.loader.WebappClassLoaderBase:web应用程序[ROOT]似乎启动了一个名为[com.alibab ...

  7. php 管理服务器内存,解决PHP-FPM进程导致的服务器内存占用

    最近php-fpm服务器经常内存偏高. 最简单也是马上见效的方法是重启服务,干脆重启服务器,这个对于某些临时进程导致的内存虚高可能有效,这里显然是不行滴.很可能影响到业务. 解决 查看服务器内存及进程 ...

  8. antimalware service executable占用内存_解决 vue 项目运行过程中内存泄漏问题

    vue-cli3.0 内存溢出 JavaScript heap out of memory vue-cli3.0构建的项目,开发过程中,可能会遇到内存溢出的情况,改动一点代码,代码编译,进程就会断掉, ...

  9. 长生命周期对象持有短生命周期对象的引用有可能发生内存泄漏(老年代引用新生代)

    具体类别 1.静态集合类引起内存泄漏 public class Test01 {static Vector v = new Vector(10);public static void main(Str ...

最新文章

  1. 入职培训笔记记录--day2续(1、运算符 2、数据的输入与输出 3、控制语句)
  2. 苹果为了不让AirTag被用来跟踪,将推出一个安卓应用
  3. python实现词语相似度计算分析_相似度计算的方法及Python实现
  4. 【Kaggle微课程】Natural Language Processing - 3. Word Vectors
  5. 难以置信的美丽,世界的数学结构
  6. php采集一言代码_用PHP制作api源码简单实现一言 / 随机一句功能
  7. 字节码指令之加载与存储指令
  8. Microsoft SilverLight
  9. Chrome浏览器打开Axure原型图
  10. Go 开发关键技术指南 | 带着服务器编程金刚经走进 2020 年
  11. 基于环信的开源即时通讯项目
  12. 【历史上的今天】12 月 23 日:Python 起源;TCP/IP 协议发明者出生;设计第一台 PC 的人诞生
  13. Raspberry 2B Ubuntu mate 16.04 *** 完美透明代理
  14. 树莓派配套系统_3.95寸配套树莓派显示屏,移植好操作系统,普及树莓派显示屏...
  15. 【算法+LeetCode题解+剑指Offer题解】算法思想、排序搜索、数据结构、数学、特殊解法、设计(全总结)
  16. appuim框架二次封装-UI自动化-自整理亲自实践
  17. k8s pod基础概念
  18. 5G商用牌照发放,“以竞争促落地”,日常5G服务可期。
  19. OM 、RAM、IROM、IRAM
  20. 操作系统-AOSOA

热门文章

  1. Linux DNS服务配置与管理详解
  2. k8s Service之NodePort
  3. JVM调优:使用G1垃圾回收器
  4. MySQL自定义变量的使用
  5. 创建springboot多模块项目
  6. win10光驱位连接计算机,windows10不能识别光驱位硬盘
  7. pythonmsgbox怎么使用_如何使用tkinter的messagebox
  8. Oracle原理:11g的体系结构
  9. 算法练习day6——190323(求中位数、堆排序、稳定性)
  10. python最早引入json的版本_详解Python在使用JSON时需要注意的编码问题