日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/10/12 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 讲述Sagit.Framework解决:双向引用导致的IOS内存泄漏(上) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:

好久沒寫文章了,最近先是重構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内存泄漏(上)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。