Notification Once

前段時間整理項目中的AppDelegate,發現很多寫在- application:didFinishLaunchingWithOptions:中的代碼都只是爲了在程序啓動時獲得一次調用機會,多爲某些模塊的初始化工作,如:

- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // ...
    [FooModule setup];
    [[BarModule sharedInstance] setup];
    // ...
    return YES;
}

其實這些代碼完全可以利用Notification的方式在自己的模塊內部搞定,分享一個巧妙的方法:

/// FooModule.m
+ (void)load
{
    __block id observer =
    [[NSNotificationCenter defaultCenter]
     addObserverForName:UIApplicationDidFinishLaunchingNotification
     object:nil
     queue:nil
     usingBlock:^(NSNotification *note) {
         [self setup]; // Do whatever you want
         [[NSNotificationCenter defaultCenter] removeObserver:observer];
     }];
}

解釋:

  • + load方法在足夠早的時間點被調用
  • block 版本的通知註冊會產生一個__NSObserver *對象用來給外部 remove 觀察者
  • block 對 observer 對象的捕獲早於函數的返回,所以若不加__block,會捕獲到 nil
  • 在 block 執行結束時移除 observer,無需其他清理工作
  • 這樣,在模塊內部就完成了在程序啓動點代碼的掛載

值得注意的是,通知是在- application:didFinishLaunchingWithOptions:調用完成後才發送的。
順便提下給 AppDelegate 瘦身的建議:AppDelegate 作爲程序級狀態變化的 delegate,應該只做路由分發的作用,具體邏輯實現代碼還是應該在分別的模塊中,這個文件應該保持整潔,除了<UIApplicationDelegate>的方法外不應該出現其他方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章