美文网首页
iOS | 关于AppDelegate瘦身的想法与实践

iOS | 关于AppDelegate瘦身的想法与实践

作者: 夏浩文 | 来源:发表于2019-09-30 01:48 被阅读0次

    随着开发的迭代升级,不断增加新的功能和职责,AppDelegate中的代码量也不断增长,致使Massive,而精通 OOP 的我们自然会想法子对其瘦身。


    AppDelegate

    什么是AppDelegate

    • AppDelegate 是应用程序的根对象,即唯一代理:
      a、其提供应用程序生命周期事件的暴露。
      b、其确保应用程序与系统以及其他应用程序正确的交互。
      c、其通常承担很多职责,这使得很难进行更改,扩展和测试。
    • 作为连接应用程序和系统的协调者,他应该总是:
      a、单一职责
      b、易于扩展
      c、易于测试

    组合模式

    • 组合模式依据树形结构来组合对象,用来表示部分以及整体层次。
      a、它隶属于结构型模式
      b、主要分🌲组装类与🍃服务类
      c、它近似于简易SOA
    • 其作用体现为
      a、服务易插拔
      b、无需额外改变 AppDelegate

    实践环节

    • 树节点(根节点):组装类
    #import <Foundation/Foundation.h>
    
    NS_ASSUME_NONNULL_BEGIN
    
    @interface AppDelegateFactory : NSObject
    
    @property (readonly) NSMutableArray *services;
    
    + (instancetype)standardFactory;
    
    @end
    
    NS_ASSUME_NONNULL_END
    
    #import "AppDelegateFactory.h"
    
    @interface AppDelegateFactory ()
    
    @property (nonatomic, strong) NSMutableArray *services;
    
    @end
    
    @implementation AppDelegateFactory
    
    + (instancetype)standardFactory {
        static AppDelegateFactory *insance = nil;
        static dispatch_once_t once;
        dispatch_once(&once, ^{
            insance = [AppDelegateFactory new];
        });
        return insance;
    }
    
    - (instancetype)init
    {
        self = [super init];
        if (self) {
            makeDefault(self);
        }
        return self;
    }
    
    NS_INLINE void makeDefault(AppDelegateFactory *factory) {
        
        [factory registeService:@"ComponentLaunchService"];
    //    [factory registeService:@"ComponentPushService"];
    //    [factory registeService:@"ComponentBackgroundService"];
    }
    
    - (void)registeService:(NSString *)serviceClassString {
        
        Class targetClass = NSClassFromString(serviceClassString);
        NSObject *service = [[targetClass alloc] init];
        
        if (![self.services containsObject:service])
            [self.services addObject:service];
    }
    
    
    #pragma mark - Lazy load
    
    /**
     生命流程中,我们有时候需要保持调用顺序,所以采用数组结构
     
     */
    - (NSMutableArray *)services {
        if (!_services) {
            _services = [NSMutableArray array];
        }
        return _services;
    }
    
    @end
    
    • 子节点(功能单元):服务类
    #import <UIKit/UIKit.h>
    
    @interface ComponentLaunchService : NSObject <UIApplicationDelegate>
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;
    
    @end
    
    @implementation ComponentLaunchService
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
        /// launch your application
    
        return YES;
    }
    
    • 植入流程
    #import "AppDelegate.h"
    #import "AppDelegateFactory.h"
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        
        self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
        
        id<UIApplicationDelegate> service;
        for(service in [AppDelegateFactory standardFactory].services){
            ///若服务响应
            if ([service respondsToSelector:_cmd]) { 
                [service application:application didFinishLaunchingWithOptions:launchOptions];
            }
        }
        
        [self.window makeKeyAndVisible];
        return YES;
    }
    
    - (void)applicationDidEnterBackground:(UIApplication *)application {
        
        id<UIApplicationDelegate> service;
        for(service in [AppDelegateFactory standardFactory].services){
            if ([service respondsToSelector:_cmd]){
                [service applicationDidEnterBackground:application];
            }
        }
        //程序进入后台,通知服务器
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application {
        
        id<UIApplicationDelegate> service;
        for(service in [AppDelegateFactory standardFactory].services){
            if ([service respondsToSelector:_cmd]){
                [service applicationWillEnterForeground:application];
            }
        }
        //程序从后台进入前台
    }
    
    - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
        
        id<UIApplicationDelegate> service;
        for(service in [AppDelegateFactory standardFactory].services){
            if ([service respondsToSelector:_cmd]){
                [service applicationDidReceiveMemoryWarning:application];
            }
        }
        //收到内存警告时
    }
    
    ///..省略以下生命周期回调方法
    @end
    

    中介者模式

    • 中介者模式提供一个中介类,该类通常处理不同类之间的通信。
      a、其隶属于行为型模式
      b、支持松耦合
    • 作用体现为:
      a、使代码易于维护
      a、降低多个对象和类之间的通信复杂性

    实践环节

    • 定义UIApplication的生命周期监听者
    import UIKit
    
    class AppLifecycleMediator: NSObject {
        private var listeners: [AppLifecycleListener]
        
        init(listeners: [AppLifecycleListener]) {
            self.listeners = listeners
            super.init()
            subscribe()
        }
        
        deinit {
            NotificationCenter.default.removeObserver(self)
        }
        
        private func subscribe() {
            NotificationCenter.default.addObserver(self, selector: #selector(onAppDidFinishLaunching), name: UIApplication.didFinishLaunchingNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(onAppDidReceiveMemoryWarning), name: UIApplication.didReceiveMemoryWarningNotification, object: nil)
        }
        
        @objc private func onAppDidFinishLaunching() {
            listeners.forEach { $0.onAppDidFinishLaunching() }
        }
        
        @objc func onAppDidReceiveMemoryWarning() {
            listeners.forEach { $0.onAppDidReceiveMemoryWarning() }
        }
    }
    
    • 定义监听协议与实现者
    import UIKit
    
    protocol AppLifecycleListener {
        func onAppDidFinishLaunching()
        func onAppDidReceiveMemoryWarning()
    }
    
    extension AppLifecycleListener {
        func onAppDidFinishLaunching() {}
        func onAppDidReceiveMemoryWarning() {}
    }
    
    //MARK: - Listeners.. (举个栗子)
    
    class SocketListener: AppLifecycleListener {
        func onAppDidFinishLaunching() {
            print("[开启长链接..]")
        }
    }
    
    • 定义静态方法,进行初始化
    extension AppLifecycleMediator {
        static func makeDefaultMediator() -> AppLifecycleMediator {
            let socketListener = SocketListener()
            return AppLifecycleMediator(listeners: [socketListener])
        }
    }
    
    • 植入中介人
    import UIKit
    
    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        // point code
        let mediator = AppLifecycleMediator.makeDefaultMediator()
    
        ///省略以下内容
    }
    
    优点在于
    • 仅需要一次初始化
    • 中介类自动订阅事件
    • 监听者Listener易于增减、对AppDelegate侵入弱

    其实我们对AppDelegate都是维系代码可维护度,职责的划分,保证不会在部分修改时牵一发而动全身,这样使得代码更灵活与茁壮,可随时插拔与复用。
    以上设计方式亦适用于,复杂模块职能划分,本文仅做简单介绍与思考~😆

    相关文章

      网友评论

          本文标题:iOS | 关于AppDelegate瘦身的想法与实践

          本文链接:https://www.haomeiwen.com/subject/nioqpctx.html