NSNotification

啥時(shí)候用:

沒有明顯層級(jí)關(guān)系的時(shí)候用.

例如在推送通知的時(shí)候,因?yàn)槲覀儾⒉恢涝谑裁磿r(shí)間點(diǎn)會(huì)觸發(fā)推送,也不知道觸發(fā)時(shí)當(dāng)前應(yīng)用出于哪一個(gè)頁面,所以使用通知.相反,如果此時(shí)通過navgation controller遍歷節(jié)點(diǎn),查詢相關(guān)節(jié)點(diǎn),做出相應(yīng)操作就不太好了.

在有明顯層級(jí)關(guān)系的時(shí)候,例如A頁面需要選擇城市,點(diǎn)擊按鈕后彈出B城市篩選頁面,選擇城市后B頁面消失,A頁面做出相應(yīng)操作.這種情況就不適合.使用Delegate/KVO/Block均好于Notification

取消地點(diǎn):

在UIViewController中,如果可以不再dealloc方法里面取消,盡量不要在.

如果可以的話,盡量在Appear(will/did)的時(shí)候進(jìn)行Add/Remove Observer.當(dāng)然要配對(duì)好.

dealloc是個(gè)挺危險(xiǎn)的方法.相信每個(gè)人都有各式各樣的問題導(dǎo)致內(nèi)存沒有釋放.盡管這可以通過查找內(nèi)存泄露來解決.

但是泄露內(nèi)存隨著iPhone硬件的提升,很多時(shí)候不并不會(huì)造成嚴(yán)重的后果.但是重復(fù)的通知發(fā)送,可能會(huì)導(dǎo)致嚴(yán)重而又詭異的bug.

盡量在安全的地方Remove.當(dāng)然,這并不代表我們可以忽略對(duì)內(nèi)存的管理.不是這個(gè)意思...

安全刪除:

在一個(gè)Object注冊(cè)了很多個(gè)通知的情況下,有人喜歡用[[NSNotificationCenter defaultCenter] removeObserver:self]來一次性刪除.

但,真的好么?
不好.

因?yàn)樗鼰o法刪除帶有block的Notifcation.

盡量配對(duì)的好,有添也有刪.

Block的Notification:

指的是這個(gè)方法:

- (id <NSObject>)addObserverForName:(NSString *)name object:(id)obj queue:(NSOperationQueue *)queue usingBlock:(void (^)(NSNotification *note))block

使用weak/strong大法.不然在調(diào)用self等的時(shí)候,會(huì)造成引用循環(huán).

似乎印象中,系統(tǒng)的block不會(huì)造成引用循環(huán),比如UIView的animation.別經(jīng)驗(yàn)主義,為了保證安全,我們甚至可以在所有的block中均使用weak/strong大法.

它會(huì)返回一個(gè)observer對(duì)象,我們需要記著刪除他.當(dāng)然,在這之前我們需要根據(jù)業(yè)務(wù)邏輯來決定持有該對(duì)象多久.

Notification Once:

詳見:Nofication Once---by孫源

在AFNetworking中也能看到此代碼,UIAlertView+AFNetworking.h中的方法:

#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000
+ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task
                                         delegate:(id)delegate
                                cancelButtonTitle:(NSString *)cancelButtonTitle
                                otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION
{
    NSMutableArray *mutableOtherTitles = [NSMutableArray array];
    va_list otherButtonTitleList;
    va_start(otherButtonTitleList, otherButtonTitles);
    {
        for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) {
            [mutableOtherTitles addObject:otherButtonTitle];
        }
    }
    va_end(otherButtonTitleList);

    __block __weak id<NSObject> observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) {
        NSError *error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey];
        if (error) {
            NSString *title, *message;
            AFGetAlertViewTitleAndMessageFromError(error, &title, &message);

            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil];
            for (NSString *otherButtonTitle in mutableOtherTitles) {
                [alertView addButtonWithTitle:otherButtonTitle];
            }
            [alertView setTitle:title];
            [alertView setMessage:message];
            [alertView show];
        }

        [[NSNotificationCenter defaultCenter] removeObserver:observer];
    }];
}
#endif

該技巧可以讓我們只注冊(cè)一次通知,使用完畢后,即被刪除.

有兩點(diǎn)需要注意.

  1. block的的notification的返回值,前面是否帶__block關(guān)鍵字是完全不一樣的,決定block對(duì)于返回值的捕獲.

  2. 除了帶上__block,盡量帶上__weak或者在block中手動(dòng)將返回值置為nil

利用ARC更好的使用Notication

Notification最常見的問題就是忘記刪除.當(dāng)出現(xiàn)此類問題的時(shí)候,非常不好排查.而引發(fā)的問題可能是巨大的,并且詭異難以debug.

所以結(jié)合ARC的特性,可以更優(yōu)雅的使用Notification.

思路是我們通過一個(gè)對(duì)象來管理通知.在注冊(cè)通知的時(shí)候,通過一定的數(shù)據(jù)結(jié)構(gòu)作好記錄.在對(duì)象dealloc的時(shí)候,刪除記錄的通知對(duì)象.

因?yàn)锳RC,所以我們不需要手動(dòng)顯示的釋放該對(duì)象.該對(duì)象釋放的時(shí)候,也就相應(yīng)的刪除了通知.

當(dāng)然,github上有更多更好的輪子.在實(shí)際生產(chǎn)中,或許我們可以使用已經(jīng)造好的輪子.

線程:

帶有block的Notification,有一個(gè)參數(shù)是queue.意思是指定執(zhí)行block的線程.如果沒有指定,則在post對(duì)象的線程中執(zhí)行.

所以,如果沒有指定線程的話,那么這個(gè)block可能會(huì)在任何一個(gè)線程中執(zhí)行,這完全取決于誰在post.

所以,如果是ui相關(guān)操作的話,最好我們指定為主線程.

另外,有A,B 2個(gè)對(duì)象,分別處于2個(gè)線程中.A post了一個(gè)notification,在notification中將會(huì)使用C對(duì)象執(zhí)行一系列方法.而B對(duì)象恰恰又釋放了C

對(duì)象.那么此時(shí)會(huì)不會(huì)出現(xiàn)問題.

答案是會(huì)的.

怎么辦呢?

盡量使用block的Notification,畢竟block會(huì)捕獲相關(guān)變量.

更多的線程請(qǐng)參考Notification與多線程---by南峰子

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市辆床,隨后出現(xiàn)的幾起案子搞莺,更是在濱河造成了極大的恐慌闯狱,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,817評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件化撕,死亡現(xiàn)場離奇詭異晓避,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)划滋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埃篓,“玉大人古毛,你說我怎么就攤上這事《夹恚” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵嫂冻,是天一觀的道長胶征。 經(jīng)常有香客問我,道長桨仿,這世上最難降的妖魔是什么睛低? 我笑而不...
    開封第一講書人閱讀 56,498評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上钱雷,老公的妹妹穿的比我還像新娘骂铁。我一直安慰自己,他們只是感情好罩抗,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評(píng)論 6 386
  • 文/花漫 我一把揭開白布拉庵。 她就那樣靜靜地躺著,像睡著了一般套蒂。 火紅的嫁衣襯著肌膚如雪钞支。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評(píng)論 1 290
  • 那天操刀,我揣著相機(jī)與錄音烁挟,去河邊找鬼。 笑死骨坑,一個(gè)胖子當(dāng)著我的面吹牛撼嗓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播欢唾,決...
    沈念sama閱讀 38,979評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼且警,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了匈辱?” 一聲冷哼從身側(cè)響起振湾,我...
    開封第一講書人閱讀 37,722評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎亡脸,沒想到半個(gè)月后押搪,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,189評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浅碾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評(píng)論 2 327
  • 正文 我和宋清朗相戀三年大州,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垂谢。...
    茶點(diǎn)故事閱讀 38,654評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厦画,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出滥朱,到底是詐尸還是另有隱情根暑,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評(píng)論 4 330
  • 正文 年R本政府宣布徙邻,位于F島的核電站排嫌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏缰犁。R本人自食惡果不足惜淳地,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評(píng)論 3 313
  • 文/蒙蒙 一怖糊、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧颇象,春花似錦伍伤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至耍贾,卻和暖如春阅爽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荐开。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評(píng)論 1 266
  • 我被黑心中介騙來泰國打工付翁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人晃听。 一個(gè)月前我還...
    沈念sama閱讀 46,382評(píng)論 2 360
  • 正文 我出身青樓百侧,卻偏偏與公主長得像,于是被迫代替她去往敵國和親能扒。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佣渴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評(píng)論 2 349

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

  • *面試心聲:其實(shí)這些題本人都沒怎么背,但是在上海 兩周半 面了大約10家 收到差不多3個(gè)offer,總結(jié)起來就是把...
    Dove_iOS閱讀 27,131評(píng)論 30 470
  • 1.OC里用到集合類是什么? 基本類型為:NSArray初斑,NSSet以及NSDictionary 可變類型為:NS...
    輕皺眉頭淺憂思閱讀 1,366評(píng)論 0 3
  • 簡述 NSNotification 是iOS中一個(gè)消息通知類辛润,存儲(chǔ)消息的一些信息;NSNotificationCe...
    小白進(jìn)城閱讀 1,095評(píng)論 1 5
  • KVC KVC (key-value observing) 是基于 NSKeyValueCoding 的一個(gè)非正式...
    漂泊海上的大土豆閱讀 404評(píng)論 0 4
  • 早上來圖書館占個(gè)坐见秤,是大部分學(xué)生的日常砂竖,要是遇到期末考試,圖書館坐無虛席鹃答。我有自己看書的工作室乎澄,里面配有電腦...
    爾古閱讀 269評(píng)論 2 0