“自釋放”在iOS開發(fā)中的應(yīng)用

轉(zhuǎn)載請注明出處:http://www.olinone.com/

今天终娃,跟大家聊聊“自釋放”思想在iOS開發(fā)中的應(yīng)用肿男,何為“自釋放”纲堵?可以簡單的理解為對象在生命周期結(jié)束后自動清理回收所有與其相關(guān)的資源或鏈接幸逆,這個清理不僅僅包括對象內(nèi)存的回收棍辕,還包括對象解耦以及附屬事件的清理等,比如定時器的自我停止还绘、KVO對象的監(jiān)聽移除等

對象內(nèi)存的回收

開發(fā)中楚昭,對象管理的基本原則——誰創(chuàng)建誰釋放。但是拍顷,非ARC工程中抚太,我們會用autorelease來標記一個對象,告訴編輯器昔案,這個對象我不負責(zé)釋放尿贫,此時,這個對象就變成了“自釋放”對象踏揣,當(dāng)其不再需要時庆亡,系統(tǒng)就會自動回收其內(nèi)存。而ARC工程中捞稿,所有對象對于我們來說都是自釋放對象又谋,很高興拼缝,我們不再需要處處留意內(nèi)存泄露的問題,可以把更多的精力放在業(yè)務(wù)邏輯上彰亥,但是這并不意味著真的沒有內(nèi)存泄露咧七,試試這個工具HJNSObjectRelease,也許你會有意想不到的收獲剩愧。

定時器的自釋放

定時器與一般對象不同猪叙,當(dāng)創(chuàng)建完定時器后,其并不會自我釋放仁卷,需要在適當(dāng)時刻invalidate穴翩。在實際開發(fā)中,也許你經(jīng)常會這樣創(chuàng)建定時器

1

self.timer=[NSTimerscheduledTimerWithTimeInterval:1.0target:selfselector:@selector(onTimerCount)userInfo:nilrepeats:YES];

然后在dealloc函數(shù)中將定時器invalidate锦积。很遺憾芒帕,你會發(fā)現(xiàn)程序永遠也不會執(zhí)行到dealloc函數(shù),因為NSTimer強引用target對象丰介,循環(huán)引用的出現(xiàn)必然導(dǎo)致內(nèi)存泄露背蟆。此時,你肯定非常想要一個weak target的定時器哮幢,很高興带膀,MSWeakTimer很好的滿足了你的需求。但是橙垢,Timer仍然沒有自我釋放垛叨,你仍然需要在dealloc中將其invalidate。那么柜某,如何才能不寫invalidate嗽元?定時器能否自釋放?我們先把這個問題放在一邊,接著往下看

KVO的自釋放

iOS開發(fā)中喂击,經(jīng)常會用到消息通知及KVO剂癌,也許你會這樣寫代碼

-(void)viewDidLoad{

[superviewDidLoad];

[[NSNotificationCenterdefaultCenter]addObserver:selfselector:@selector(onNotice)name:@"NoticeIdentifier"object:nil];

[selfaddObserver:targetforKeyPath:@"keyPath"options:NSKeyValueObservingOptionNewcontext:nil];

}

-(void)dealloc{

[[NSNotificationCenterdefaultCenter]removeObserver:selfname:@"NoticeIdentifier"object:nil];

[selfremoveObserver:targetforKeyPath:@"keyPath"];

}

隨著時間的積累,你會非常習(xí)慣這種寫法翰绊,并且蘋果也是這樣推薦的佩谷。但是慢慢你會發(fā)現(xiàn)所有對象的Dealloc函數(shù)都只做了這一件事,能不能不做這件事监嗜?FBKVOController也許會是一個不錯的選擇谐檀,Demo可以這樣寫

[self.KVOControllerobserve:clockkeyPath:@"date"options:NSKeyValueObservingOptionInitial|NSKeyValueObservingOptionNewblock:^(ClockView*clockView,Clock*clock,NSDictionary*change){

clockView.date=change[NSKeyValueChangeNewKey];

}];

FBKVOController的實現(xiàn)原理可以查看這篇文章,通過自釋放的實現(xiàn)秤茅,程序猿不再關(guān)心remove監(jiān)聽稚补。但是其還是有一定的局限性——對象無法監(jiān)聽自己的屬性,如果你的代碼是這樣的

[self.KVOControllerobserve:selfkeyPath:@"date"options:NSKeyValueObservingOptionNewblock:^(NSDictionary*change){

// to do

}];

很遺憾框喳,循環(huán)引用的問題又出現(xiàn)课幕,因為FBKVOController中的NSMapTable對象會retain key對象厦坛,具體代碼如下

[_objectInfosMapsetObject:infosforKey:object];

那么,FBKVOController是如何做到自釋放的乍惊?可以歸納為四個字——動態(tài)屬性杜秸。其為觀察者綁定動態(tài)屬性self.KVOController,動態(tài)綁定的KVOController會隨著觀察者的釋放而釋放润绎,KVOController在自己的dealloc函數(shù)中移除KVO監(jiān)聽撬碟,巧妙的將觀察者的remove轉(zhuǎn)移到其動態(tài)屬性的dealloc函數(shù)中。

可是莉撇,這又有什么用呢蛤?對象仍然無法監(jiān)聽自己的屬性,還是要重寫set函數(shù)棍郎。HTBKVObservation也許會改變你的想法其障,其和FBKVOController來自同一人,代碼可以這樣寫

self.anObservation=[HTBKVObservationobserve:anObjectToObservekeyPath:@"observeMe"options:0callback:^(HTBKVObservation*observation,NSDictionary*changeDictionary){

// to do

}];

HTBKVObservation并沒用采用動態(tài)屬性涂佃,而是采用屬性的方式實現(xiàn)自釋放励翼。可以監(jiān)控對象自己的屬性辜荠,但是需要創(chuàng)建屬性HTBKVObservation汽抚。這里我對其做了一點擴展,方便使用伯病,代碼可以這樣寫[selfobserve:selfkeyPath:@"KVOPath"options:NSKeyValueObservingOptionNewcallback:^(HTBKVObservation*observation,NSDictionary*changeDictionary){

// to do

}];

FBKVOControllerHTBKVObservation通過屬性或動態(tài)屬性巧妙的將KVO的remove轉(zhuǎn)移給第三者造烁,實現(xiàn)了KVO事件的解耦,為自釋放的實現(xiàn)提供了一種借鑒思路

NSNotification的自釋放

談完 KVO狱从,再來談?wù)凬SNotification膨蛮。針對Notification叠纹,ReactiveCocoa做了很好的封裝季研,網(wǎng)上有很多介紹其如何使用的文章,在此不再累述誉察。直接看代碼

[[[NSNotificationCenterdefaultCenter]rac_addObserverForName:UIKeyboardDidChangeFrameNotificationobject:nil]subscribeNext:^(idx){

// to do

}

];

簡單明了与涡,當(dāng)觀察者dealloc,很遺憾持偏,NSNotification并沒用移除驼卖,因為對象并沒用自釋放,正確代碼應(yīng)該是這樣

1

2

3

4[[[[NSNotificationCenterdefaultCenter]rac_addObserverForName:UIKeyboardDidChangeFrameNotificationobject:nil]takeUntil:self.rac_willDeallocSignal]subscribeNext:^(idx){

// to do

}

];

ReactiveCocoa自釋放的原理與FBKVOController不同鸿秆,其并不是通過屬性或者動態(tài)屬性的方式實現(xiàn)酌畜,而是通過swizzling觀察對象的dealloc函數(shù),在自定義dealloc函數(shù)實施清理卿叽,但不是默認清理桥胞,需要我們告訴它willDeallocSignal的時候完成所有清理工作恳守。

除了定時器、KVO贩虾、NSNotification催烘,包括封裝的某個功能對象,比如HttpRequest缎罢,或者數(shù)據(jù)庫ListSql等伊群,合理的利用自釋放可以給使用者帶來更多的便利,同時也會減少 crash 產(chǎn)生的概率策精。實現(xiàn)自釋放的方法可以總結(jié)為以下三種方式

動態(tài)屬性的自釋放

@property 的自釋放

swizzling dealloc的自釋放

可以根據(jù)具體業(yè)務(wù)或者設(shè)計思想選擇對應(yīng)的實現(xiàn)方式舰始,這是一種思想,更是一個習(xí)慣咽袜。相信你會愛上它蔽午,畢竟誰不喜歡簡潔的實現(xiàn)方式了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酬蹋,一起剝皮案震驚了整個濱河市及老,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌范抓,老刑警劉巖骄恶,帶你破解...
    沈念sama閱讀 219,270評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異匕垫,居然都是意外死亡僧鲁,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評論 3 395
  • 文/潘曉璐 我一進店門象泵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來寞秃,“玉大人,你說我怎么就攤上這事偶惠〈菏伲” “怎么了?”我有些...
    開封第一講書人閱讀 165,630評論 0 356
  • 文/不壞的土叔 我叫張陵忽孽,是天一觀的道長绑改。 經(jīng)常有香客問我,道長兄一,這世上最難降的妖魔是什么厘线? 我笑而不...
    開封第一講書人閱讀 58,906評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮出革,結(jié)果婚禮上造壮,老公的妹妹穿的比我還像新娘。我一直安慰自己骂束,他們只是感情好耳璧,可當(dāng)我...
    茶點故事閱讀 67,928評論 6 392
  • 文/花漫 我一把揭開白布硝全。 她就那樣靜靜地躺著,像睡著了一般楞抡。 火紅的嫁衣襯著肌膚如雪伟众。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評論 1 305
  • 那天召廷,我揣著相機與錄音凳厢,去河邊找鬼。 笑死竞慢,一個胖子當(dāng)著我的面吹牛先紫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播筹煮,決...
    沈念sama閱讀 40,442評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼遮精,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了败潦?” 一聲冷哼從身側(cè)響起本冲,我...
    開封第一講書人閱讀 39,345評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎劫扒,沒想到半個月后檬洞,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡沟饥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,984評論 3 337
  • 正文 我和宋清朗相戀三年添怔,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贤旷。...
    茶點故事閱讀 40,117評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡广料,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出幼驶,到底是詐尸還是另有隱情艾杏,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評論 5 346
  • 正文 年R本政府宣布县遣,位于F島的核電站糜颠,受9級特大地震影響汹族,放射性物質(zhì)發(fā)生泄漏萧求。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,462評論 3 331
  • 文/蒙蒙 一顶瞒、第九天 我趴在偏房一處隱蔽的房頂上張望夸政。 院中可真熱鬧,春花似錦榴徐、人聲如沸守问。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽耗帕。三九已至穆端,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仿便,已是汗流浹背体啰。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留嗽仪,地道東北人荒勇。 一個月前我還...
    沈念sama閱讀 48,377評論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像闻坚,于是被迫代替她去往敵國和親沽翔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,060評論 2 355

推薦閱讀更多精彩內(nèi)容