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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

浅析NSTimer CADisplayLink内存泄露

發布時間:2025/3/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 浅析NSTimer CADisplayLink内存泄露 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

偶得前言

本篇文章中我們主要談談NSTimer\CADisplayLink在使用過程中牽扯到內存泄露的相關問題及解決思路(文章末尾會附上Demo),有時候我們在不知情的情況容易入坑,最關鍵你還不知道自己掉坑了,閑話不多說,讓我們開始進入正題。

NSRunLoop與定時器

我們先來回顧一下NSRunLoop對NSTimer\CADisplayLink的影響。(為了方便,以下統稱定時器)

大家都知道定時器的運行需要結合一個NSRunLoop(有疑惑的同學可以查看Xcode Document,此處不細說),同時NSRunLoop對該定時器會有一個強引用,這也是為什么我們不對NSRunLoop中的定時器進行強引的原因(如:self.timer = timer, 此代碼可省略)。

- invalidate的作用

由于NSRunLoop對定時器有著牽引,那么問題就來了,那么定時器怎樣才能被釋放掉呢(先不考慮使用removeFromRunLoop:),此時- invalidate函數的作用就來了,我們來看看官方就此函數的介紹:

Removes the object from all runloop modes (releasing the receiver if it has been implicitly retained) and releases the 'target' object.

據官方介紹可知,- invalidate做了兩件事,首先是把本身(定時器)從NSRunLoop中移除,然后就是釋放對‘target’對象的強引用。從而解決定時器帶來的內存泄露問題。

內存泄露在哪?

看到這里我們可能會有點懵逼,先上一個圖(為了方便講解,途中箭頭指向誰就代表強引誰):

此處我們必須明確,在開發中,如果創建定時器只是簡單的計時,不做其他引用,那么timer對象與myClock對象循環引用的問題就可以避免(即省略self.timer = timer,前文已經提到過,不再闡述),即圖中箭頭5可避免。

雖然孤島問題已經避免了,但還是存在問題,因為myClock對象被UIViewController以及timer引用(timer直接被NSRunLoop強引用著),當UIViewController控制器被UIWindow釋放后,myClock不會被銷毀,從而導致內存泄露。

講到這里,有些人可能會說對timer對象發送一個invalidate消息,這樣NSRunLoop即不會對timer進行強引,同時timer也會釋放對myClock對象的強引,這樣不就解決了嗎?沒錯,內存泄露是解決了。

但是,這并不是我們想要的結果,在開發中我們可能會遇到某些需求,只有在myClock對象要被釋放時才去釋放timer(此處要注意釋放的先后順序及釋放條件),如果提前向timer發送了invalidate消息,那么myClock對象可能會因為timer被提前釋放而導致數據錯了,就像鬧鐘失去了秒針一樣,就無法正常工作了。所以我們要做的是在向myClock對象發送dealloc消息前在給timer發送invalidate消息,從而避免本末倒置的問題。這種情況就像一個死循環(因為如果不給timer發送invalidate消息,myClock對象根本不會被銷毀,dealloc方法根本不會執行),那么該怎么做呢?

我們如何解決?

現在我們已經知道內存泄露在哪了,也知道原因是什么,那么如何解決,或者說怎樣優雅的解決這問題呢?方式有很多.
a.NSTimer Target

為了解決timer與myClock之間類似死鎖的問題,我們會將定時器中的‘target’對象替換成定時器自己,采用分類實現。

#import?"NSTimer+TXTimerTarget.h"@implementation?NSTimer?(TXTimerTarget)+?(NSTimer?*)tx_scheduledTimerWithTimeInterval:(NSTimeInterval)interval?repeat:(BOOL)yesOrNo?block:(void?(^)(NSTimer?*))block{????return?[self?scheduledTimerWithTimeInterval:interval?target:self?selector:@selector(startTimer:)?userInfo:[block?copy]?repeats:yesOrNo]; }+?(void)startTimer:(NSTimer?*)timer?{????void?(^block)(NSTimer?*timer)?=?timer.userInfo;????if?(block)?{block(timer);} }@end

b.NSTimer Proxy

這種方式就是創建一個NSProxy子類TXTimerProxy(不太清楚NSProxy的同學可以去查一下相關資料哈),TXTimerProxy的作用是什么呢?就是什么也不做,可以說只會重載消息轉發機制,如果創建一個TXTimerProxy對象將其作為timer的‘target’,專門用于轉發timer消息至myClock對象,那么問題是不是就解決了呢?答案:是的。

NSTimer?*timer?=?[NSTimer?scheduledTimerWithTimeInterval:0.25?target:[TXTimerProxy?timerProxyWithTarget:self]?selector:@selector(startTimer)?userInfo:nil?repeats:YES];[[NSRunLoop?currentRunLoop]?addTimer:timer?forMode:NSRunLoopCommonModes];self.timer?=?timer;

實現詳情文章末尾會附上Demo,感興趣的同學可以去看看哈,有什么問題可以直接問,互相交流。

c.NSTimer Block

還有一種方式就是采用Block,iOS 10增加的API。

+?scheduledTimerWithTimeInterval:repeats:block:

The execution body of the timer; the timer itself is passed as the parameter to this block when executed to aid in avoiding cyclical references

有點類似a方式,此處不再詳述。

//NSTimer?Block(解決self內存泄露)?模擬器會崩潰//API_AVAILABLE(macosx(10.12),?ios(10.0),?watchos(3.0),?tvos(10.0));NSTimer?*timer?=?[NSTimer?scheduledTimerWithTimeInterval:0.25?repeats:YES?block:^(NSTimer?*?_Nonnull?timer)?{????NSLog(@"TXNSTimerBlockController?timer?start"); }];[[NSRunLoop?mainRunLoop]?addTimer:timer?forMode:NSRunLoopCommonModes];self.timer?=?timer;

此處以NSTimer舉例,CADisplayLink不再詳述(方式都是一樣)。




本文轉自lzwxx 51CTO博客,原文鏈接:http://blog.51cto.com/13064681/1943387

總結

以上是生活随笔為你收集整理的浅析NSTimer CADisplayLink内存泄露的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 免费一级suv好看的国产网站 | 一区二区三区四区免费 | 肉丝美足丝袜一区二区三区四 | 午夜不卡在线 | 男人的天堂色 | 蜜臀av一区二区 | 神马午夜在线观看 | 日韩 欧美 中文 | 夜夜嗨av禁果av粉嫩avhd | 91香蕉一区二区三区在线观看 | 一区二区三区四区人妻 | 99re在线精品 | 亚洲国产精品一区二区三区 | 天天舔天天干天天操 | 久久高清一区 | 精品在线播放视频 | 日韩porn| 欧美三级色图 | 久久免费影院 | 综合伊人av | 性色av蜜臀av浪潮av老女人 | 免费av中文字幕 | 美乳在线播放 | 综合av| 性欧美大战久久久久久久 | 午夜偷拍视频 | 久草热线 | 欧美日韩亚洲不卡 | 一级高清毛片 | av不卡一区二区 | 麻豆porn | 欧美视频四区 | 无码粉嫩虎白一线天在线观看 | 国产极品久久久 | 日韩av在线看免费观看 | 特级西西人体444www | 午夜国产一区二区三区 | 黑人巨大精品欧美一区免费视频 | 羞羞色视频 | 欧美亚洲在线观看 | jzzjzz日本丰满少妇 | 精品成人久久久 | 日美韩一区二区三区 | 国产精品日韩一区二区三区 | 糖心av| 蓝牛av| 超碰caoprom| 51ⅴ精品国产91久久久久久 | 国产又粗又猛又爽又黄的网站 | 在线播放你懂得 | 性欧美13一14内谢 | 3p视频在线 | 久久久久五月天 | 亚洲成人网在线播放 | 日韩成人午夜电影 | 精品一区二区三区在线播放 | 国产盗摄一区二区 | 在线观看免费高清 | 97超碰在| 亚洲高清资源 | 欧美色噜噜 | 日韩精品无码一区二区 | 亚洲综合激情网 | 黄色网址链接 | 97久久国产精品 | 黑人干亚洲人 | 男人桶进美女尿囗 | 国产精品高潮呻吟视频 | 少妇粉嫩小泬喷水视频www | 国产精品第一国产精品 | 最新色网址 | 亚洲午夜伦理 | 99国产精品自拍 | 黑人巨大精品欧美黑白配亚洲 | 国产人久久人人人人爽 | 超碰人人擦 | 日韩精品一级 | 欧美成人午夜77777 | 91大神视频在线播放 | 色亚洲视频| 亚洲老老头同性老头交j | 日本在线 | 91九色porn | 农民人伦一区二区三区 | 成人午夜视频免费看 | 日韩欧美无 | 一级片免费网址 | 欧美bbbbb性bbbbb视频 | 人禽l交视频在线播放 视频 | 日韩一区二区三区四区 | 毛片av网址 | 手机在线成人 | 啪在线视频| 超碰成人久久 | 黄色大片网站 | 亚洲视频在线免费播放 | 色屋永久 | 女女av在线 | 国产一区成人 |