AppDelegate的解耦和瘦身

openword_1 8年前發布 | 9K 次閱讀 iOS開發 移動開發

嚴格來講,AppDelegate除了負責應用生命周期之外,不應該再有多余的責任。

但在iOS 實際開發過程中,很多人習慣將全局變量定義在 AppDelegate 中,因為任何項目都會訪問 AppDelegate,但如此這般,AppDelegate就變得更加臃腫。

在大型項目中,想要接觸耦合和模塊化時,都不利于AppDelegate的維護。

所以最好的辦法就是

  1. 將很多全局變量放在AppDelegate上,將AppDelegate作為一個依賴中心店,雖然很多模塊可以訪問全局變量,但會產生相互依賴,不利于模塊化開發;
  2. 不同的模塊,會根據需要在AppDelegate的不同生命周期方法中,調用各種方法。比如在程序啟動時在 application:didFinishLaunchingWithOptions: 內注冊一個初始化方法;

怎么解決上述兩個問題:

對于Question1, 我們可以將全局變量移除,最簡單的解決方式就是將類實現為單例,各個類可以提供單例來實現全局訪問。

Question2: 既想解除各個模塊和AppDelegate的耦合,又想要在不同生命周期完成方法的調用,最好的辦法就是暴漏出一個鉤子方法,這樣每個模塊就可以知曉不同的生命周期,然后執行不同操作。

今天看到豆瓣提供的第三方庫 FRDModuleManager ,有些思考,寫下來與大家共享下。

FRDModuleManager的核心是利用了鉤子方法,在 FRDModuleManager 被 UIApplicationDelegate 各方法內留下的鉤子調用時,會調用注冊的每個模塊的相同的方法。這樣每個模塊就都知曉了應用的生命周期。

具體代碼如下:

FRDModuleManager類:

  1. 一個單例對象
  2. 同時定義了從 plist 文件中添加 module 的單例方法
  3. 里面包含一個遵守UIApplicationDelegate的協議FRDModule

凡是遵守了FRDModule的模塊都可以獲取生命周期的方法,然后根據需要,在不同生命周期方法中,完成必要操作,如此即可充分的解耦。

具體的實例可以參考一下代碼:

  1. 加載所有模塊,文件從 plist中獲取,將不同的模塊填寫到 plist 文件中。

    NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"ModulesRegister" ofType:@"plist"];
     FRDModuleManager *manager = [FRDModuleManager sharedInstance];
     [manager loadModulesWithPlistFile:plistPath];
  2. 在 UIApplicationDelegate 各方法中留下鉤子

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
     NSString* plistPath = [[NSBundle mainBundle] pathForResource:@"ModulesRegister" ofType:@"plist"];
       FRDModuleManager *manager = [FRDModuleManager sharedInstance];
       [manager loadModulesWithPlistFile:plistPath];
    
       [manager application:application didFinishLaunchingWithOptions:launchOptions];
    
       return YES;
     }
    
     - (void)applicationWillResignActive:(UIApplication *)application {
       [[FRDModuleManager sharedInstance] applicationWillResignActive:application];
     }
    
     - (void)applicationDidEnterBackground:(UIApplication *)application {
       [[FRDModuleManager sharedInstance] applicationDidEnterBackground:application];
     }
    
     - (void)applicationWillEnterForeground:(UIApplication *)application {
       [[FRDModuleManager sharedInstance] applicationWillEnterForeground:application];
     }
    
     - (void)applicationDidBecomeActive:(UIApplication *)application {
       [[FRDModuleManager sharedInstance] applicationDidBecomeActive:application];
     }
    
     - (void)applicationWillTerminate:(UIApplication *)application {
       [[FRDModuleManager sharedInstance] applicationWillTerminate:application];
     }
  1. 在特定模塊,根據需求完成注冊即可,比如以下為FRDTimelineModule的模塊
//這是一個遵守了FRDModule協議的模塊FRDTimelineModule.h
@interface FRDTimelineModule : NSObject<FRDModule>

@end
//FRDTimelineModule.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      NSLog(@"%@  Timeline", NSStringFromSelector(_cmd));
      return YES;
    }

 

來自:http://www.jianshu.com/p/6ee6aad1b4e0

 

 本文由用戶 openword_1 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!