編碼篇-繼承+通知看方法的實現(xiàn)和delloc方法的調(diào)用


場景

UITableViewCell B繼承自 UITableViewCell A蜜笤, UITableViewCell A 注冊了名為A的通知靴迫,通知綁定的方法為 方法 A惕味;UITableViewCell B 注冊了名為B的通知,通知綁定的方法為 方法 B玉锌。

問題

點擊進入UITableViewCell B中后返回名挥,再進入到 UITableViewCell A中,觸發(fā)通知A主守,此時會崩潰禀倔,崩潰在 UITableViewCell B 的方法B中榄融,( 這里說一下,方法B和方法A是一樣的)

分析原因

Paste_Image.png

如圖所示:UITableViewCell A和UITableViewCell B的關(guān)系和方法的調(diào)用關(guān)系大致如此蹋艺,崩潰的原因是剃袍,由于 方法B和方法A是一樣的,UITableViewCell B 繼承與 UITableViewCell A捎谨,由于

Paste_Image.png

UITableViewCell B在初始化的時候調(diào)用了 UITableViewCell A中的初始化方法,所以由于繼承的機制憔维,實際上 UITableViewCell B注冊了兩個通知:通知A和通知B涛救。由于方法B和方法A是一樣的,所以UITableViewCell B中的通知A調(diào)用方法A的時候业扒,實際上就調(diào)用了方法B检吆,(當子類的方法列表中有和父類的方法列表中的方法一樣的情況下,會調(diào)用子類中的方法程储,而不調(diào)用父類中的方法蹭沛,也就是重寫),而實際上 UITableViewCell B 中的方法B設(shè)計上不是為 通知A服務(wù)的章鲤,其中調(diào)用的一些未知的數(shù)據(jù)摊灭,所有就出現(xiàn)了崩潰。

有一個問題:為什么從 UITableViewCell B中POP出后败徊,UITableViewCell B沒有被釋放呢帚呼?,就是因為UITableViewCell B沒有在頁面被 POP后被釋放掉皱蹦,才會出現(xiàn)這樣的 Crash煤杀,那么為什么沒被釋放呢

dealloc的不被調(diào)用的情況。

ARC下,控制器在被pop后移出棧后會被釋放沪哺,但有些時候會發(fā)現(xiàn)控制器出棧的時候不會調(diào)用dealloc方法沈自,系統(tǒng)可以幫我們釋放該對象,及其包含的對象;但是卻無法釋放不屬于該對象的一些東西,就造成了 對象的dealloc方法不被調(diào)用。而且重寫該方法時不能顯式調(diào)用[super dealloc]辜妓,和繼承中先加載父類再加載子類相反枯途,注銷時先注銷子類之后再注銷父類。因為系統(tǒng)會自動幫你調(diào)用父類的dealloc方法嫌拣。

  • 1.通知的觀察者,或KVO的觀察者

由于通知中心是系統(tǒng)的一個單例,你在注冊通知的觀察者時,實際上是在通知中心注冊的,
這時,即使ARC下系統(tǒng)幫我們釋放了對象,但是在通知中心的觀察還是沒有移除,那么當有
該通知時,依然會嘗試調(diào)用該對象的接受通知的方法,這可能會導致一些問題.

  • 2.對象強委托

對于其他的對象來把你當做委托 delegate時,并且是 強引用時,即時你自身被釋放,但是引用你的對象依然還在,這時需要在引用你的對象移除該delegate

  • 3.一些其它的資源柔袁,類似地圖頁面。C語言寫的一些好內(nèi)存的類文件异逐,
  • 4.控制器中NSTimer沒有被銷毀

當viewController中存在NSTimer時捶索,需要特別注意,當調(diào)用[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES]時灰瞻,因為 target:self 腥例,也就是引用了當前viewController辅甥,導致控制器的引用計數(shù)加1,如果沒有將這個NSTimer 銷毀燎竖,它將一直保留該viewController璃弄,無法釋放,也就不會調(diào)用dealloc方法构回。所以夏块,需要在viewWillDisappear之前需要把控制器用到的NSTimer銷毀.

[timer invalidate]; // 銷毀
timertimer = nil; // 置nil
  • 5.viewController中block的循環(huán)引用在ARC下,

block會把它里面的所有對象強引用纤掸,包括當前控制器self脐供,因此有可能會出現(xiàn)循環(huán)引用的問題。比如viewController中有個block屬性借跪,在block中又強引用了self或者其他成員變量政己,那么這個viewController與自己的block屬性就形成循環(huán)引用,導致viewController無法釋放掏愁。

很顯然歇由,UITableViewCell B不被釋放是因為在初始化的時候注冊的通知沒有移除,也沒有機會移除了果港,造成的每創(chuàng)建一個UITableViewCell B 都不會被釋放沦泌,而是一直在內(nèi)存中。

驗證猜想

我們修改 方法B 使方法A和 方法B不一樣京腥。在方法A中打印當前類名赦肃,然后多次 push進入UITableViewCell B中后再次進入 UITableViewCell A中,觸發(fā)通知A公浪,調(diào)用方法A會出現(xiàn)下面的情況:

Paste_Image.png

跟我們猜想的一樣他宛,由于很多不同的UITableViewCell B 被創(chuàng)建,(都注冊了倆通知欠气,由于繼承的關(guān)系厅各,雖然UITableViewCell B 中沒有寫 UITableViewCell A的一些方法,但是UITableViewCell B的方法列表中還是會有 那些方法预柒,只是省去了書寫而已队塘,書寫在了父類文件中)而且沒有被銷毀,所以當UITableViewCell A 中的通知A被觸發(fā)時宜鸯,同樣的 UITableViewCell B 中的通知A 也被觸發(fā)憔古,由于UITableViewCell B 中沒有方法A,于是就去執(zhí)行了 父類(UITableViewCell A)中的方法A淋袖,于是就出現(xiàn)了 上圖那樣的場景鸿市。

解決辦法

  • 單純避免崩潰的話,在UITableViewCell B中第一個 空的方法A 即可,或者把方法B 和 方法A 修改為不同即可焰情。

  • 可是這樣陌凳,UITableViewCell A中的方法A依然會被執(zhí)行很多次。

 #最后一個參數(shù)是表示會對哪個發(fā)送者對象發(fā)出的事件作出響應(yīng)内舟,nil 時表示接受所有發(fā)送者的事件合敦。,
 #所以我們這里把 object:self ,即可只接受自己觸發(fā)的通知验游,而不會接受到其它 UITableViewCell觸發(fā)的通知了
 #添加之前先移除所有監(jiān)聽充岛,可以解決多次注冊相同監(jiān)聽的問題。
[[NSNotificationCenter defaultCenter]removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(goodtongzhi:) name:@"goodPopAlert" object:self];

  - (void)goodtongzhi :(NSNotification *)sender
  {
   #如果不是自己觸發(fā)的通知就不處理批狱。
    if (![sender.object isEqual:self]) {
        return;
    }
    
    NSDictionary *dataDic = sender.userInfo;
    NSLog(@"你好我是 %@",self.class);
    if ([dataDic[@"index"] integerValue] == self.tag) {
        
        goods =dataDic[@"data"];
        rightTextLablel[0].text = goods.name;
        rightTextLablel[2].text = goods.danwei;
        baozhiqiTexttF.text = goods.baizhiqi;
        rightTextLablel[4].text = goods.baizhiqidanwei;
    }
  }

小結(jié)

雖然我們解決了崩潰裸准,也解決了方法的多次調(diào)用,看似達到了要求赔硫,其實在 UITableViewCell中注冊通知是很不好的方法,這樣會造成很多 UITableViewCell 無法被釋放盐肃,一直在內(nèi)存中爪膊,使用 多層次的Block回調(diào),一樣可以達到通知的效果砸王,而且不會造成UITableViewCell無法被釋放的問題推盛,本文詳細分析這個問題,旨在希望大家寫程序時注意這個問題谦铃。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末耘成,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子驹闰,更是在濱河造成了極大的恐慌瘪菌,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘹朗,死亡現(xiàn)場離奇詭異师妙,居然都是意外死亡,警方通過查閱死者的電腦和手機屹培,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門默穴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人褪秀,你說我怎么就攤上這事蓄诽。” “怎么了媒吗?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵仑氛,是天一觀的道長。 經(jīng)常有香客問我蝴猪,道長调衰,這世上最難降的妖魔是什么膊爪? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮嚎莉,結(jié)果婚禮上米酬,老公的妹妹穿的比我還像新娘。我一直安慰自己趋箩,他們只是感情好赃额,可當我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著叫确,像睡著了一般跳芳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竹勉,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天飞盆,我揣著相機與錄音,去河邊找鬼次乓。 笑死吓歇,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的票腰。 我是一名探鬼主播城看,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼杏慰!你這毒婦竟也來了测柠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤缘滥,失蹤者是張志新(化名)和其女友劉穎轰胁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體完域,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡软吐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吟税。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片凹耙。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖肠仪,靈堂內(nèi)的尸體忽然破棺而出肖抱,到底是詐尸還是另有隱情,我是刑警寧澤异旧,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布意述,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荤崇。R本人自食惡果不足惜拌屏,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望术荤。 院中可真熱鬧倚喂,春花似錦、人聲如沸瓣戚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽子库。三九已至舱权,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間仑嗅,已是汗流浹背宴倍。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仓技,地道東北人啊楚。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像浑彰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拯辙,可洞房花燭夜當晚...
    茶點故事閱讀 44,974評論 2 355

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

  • *面試心聲:其實這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,146評論 30 470
  • 1.OC里用到集合類是什么郭变? 基本類型為:NSArray,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,378評論 0 3
  • 37.cocoa內(nèi)存管理規(guī)則 1)當你使用new涯保,alloc或copy方法創(chuàng)建一個對象時诉濒,該對象的保留計數(shù)器值為1...
    如風家的秘密閱讀 847評論 0 4
  • 父類實現(xiàn)深拷貝時,子類如何實現(xiàn)深度拷貝夕春。父類沒有實現(xiàn)深拷貝時未荒,子類如何實現(xiàn)深度拷貝。? 深拷貝同淺拷貝的區(qū)別:淺拷...
    JonesCxy閱讀 1,008評論 1 7
  • 今天看到一篇文章這樣寫道及志,“不熬夜已經(jīng)成了我們時代最難的自律片排,能好好睡覺的年輕人都是潛力股∷俪蓿”感覺自己天天晚睡率寡,是...
    哎喲喂Gg閱讀 248評論 0 0