學(xué)習(xí)筆記

模塊化

涉及到的類

  • 底層:UPCore
  • 模塊管理:moduleManager
  • 協(xié)議:UPModuleProtocol
  • 項(xiàng)目入口:APPDelegate
  • 具體模塊:UPPush

邏輯關(guān)系
(+ load 作為 Objective-C 中的一個(gè)方法,與其它方法有很大的不同。它只是一個(gè)在整個(gè)文件被加載到運(yùn)行時(shí),在 main 函數(shù)調(diào)用之前被 ObjC 運(yùn)行時(shí)調(diào)用的鉤子方法)

  1. 模塊向UPCore注冊(cè)
UPPushModule.h
+ (void)load
{
    [UPCore registerModuleClass:[self class]];
}

2.在UPCore中初始化并調(diào)用UPModuleManager

+ (void)registerModuleClass:(Class)moduleClass
{
    [[UPModuleManager sharedInstance] registerModuleClass:moduleClass];
}

3.初始化單例UPModuleManager,初始化字典

+ (instancetype)sharedInstance
{
    static dispatch_once_t predicate;
    static id UPModuleManagerInstance = nil;
    dispatch_once(&predicate, ^{
      UPModuleManagerInstance = [[self alloc] init];
    });
    return UPModuleManagerInstance;
}
- (instancetype)init
{
    if (self = [super init]) {
        _modules = [NSMutableArray array];
        _moduleEventSelectorInfoDictionary = @{ @(UPMSetupEvent) : kUPModuleSetupSelector,
                                                @(UPMInitEvent) : kUPModuleInitSelector,
                                                @(UPMTearDownEvent) : kUPModuleTearDownSelector,
                                                @(UPMWillResignActiveEvent) : kUPModuleWillResignActiveSelector,
                                                @(UPMDidEnterBackgroundEvent) : kUPModuleDidEnterBackgroundSelector,
                                                @(UPMWillEnterForegroundEvent) : kUPModuleWillEnterForegroundSelector,
                                                @(UPMDidBecomeActiveEvent) : kUPModuleDidBecomeActiveSelector,
                                                @(UPMWillTerminateEvent) : kUPModuleWillTerminateSelector,
                                                @(UPMDidReceiveMemoryWarningEvent) : kUPModuleDidReceiveMemoryWarningSelector,
                                                @(UPMDidFailToRegisterForRemoteNotificationsEvent) : kUPModuleDidFailToRegisterForRemoteNotificationsSelector,
                                                @(UPMDidRegisterForRemoteNotificationsEvent) : kUPModuleDidRegisterForRemoteNotificationsSelector,
                                                @(UPMDidReceiveRemoteNotificationEvent) : kUPModuleDidReceiveRemoteNotificationSelector,
                                                @(UPMDidReceiveLocalNotificationEvent) : kUPModuleDidReceiveLocalNotificationSelector,
                                                @(UPMDidRegisterUserNotificationSettings) : kUPMDidRegisterUserNotificationSettingsSelector };
    }
    return self;
}
- (void)registerModuleClass:(Class)moduleClass
{
    if (moduleClass == nil) {
        UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失敗!該模塊類為nil!", __PRETTY_FUNCTION__, __LINE__);
        return;
    }
    if (![moduleClass conformsToProtocol:@protocol(UPModuleProtocol)]) {
        UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失??!該模塊類未實(shí)現(xiàn)UPModuleProtocol協(xié)議!", __PRETTY_FUNCTION__, __LINE__);
        return;
    }
    NSString *moduleClassName = NSStringFromClass(moduleClass);
    if (![moduleClassName isKindOfClass:[NSString class]] || moduleClassName.length == 0) {
        UPLogError(@"CoreHive", @"%s[%d]模塊注冊(cè)失?。≡撃K類為空!", __PRETTY_FUNCTION__, __LINE__);
        return;
    }
    if ([self.modules containsObject:moduleClassName]) {
        UPLogWarning(@"CoreHive", @"%s[%d]該模塊類(%@)已注冊(cè)過!", __PRETTY_FUNCTION__, __LINE__, moduleClassName);
        return;
    }
    [self.modules addObject:moduleClassName];
}

4.使用const聲明的selector對(duì)應(yīng)value,使用枚舉聲明key

UPModuleManager.m

NSString *kUPModuleClassName = @"moduleClass";
NSString *const kUPModuleSetupSelector = @"moduleSetup:";
NSString *const kUPModuleInitSelector = @"moduleInit:";
NSString *const kUPModuleTearDownSelector = @"moduleTearDown:";
NSString *const kUPModuleWillResignActiveSelector = @"moduleWillResignActive:";
NSString *const kUPModuleDidEnterBackgroundSelector = @"moduleDidEnterBackground:";
NSString *const kUPModuleWillEnterForegroundSelector = @"moduleWillEnterForeground:";
NSString *const kUPModuleDidBecomeActiveSelector = @"moduleDidBecomeActive:";
NSString *const kUPModuleWillTerminateSelector = @"moduleWillTerminate:";
NSString *const kUPModuleDidReceiveMemoryWarningSelector = @"moduleDidReceiveMemoryWarning:";
NSString *const kUPModuleDidFailToRegisterForRemoteNotificationsSelector = @"moduleDidFailToRegisterForRemoteNotifications:";
NSString *const kUPModuleDidRegisterForRemoteNotificationsSelector = @"moduleDidRegisterForRemoteNotifications:";
NSString *const kUPModuleDidReceiveRemoteNotificationSelector = @"moduleDidReceiveRemoteNotification:";
NSString *const kUPModuleDidReceiveLocalNotificationSelector = @"moduleDidReceiveLocalNotification:";
NSString *const kUPMDidRegisterUserNotificationSettingsSelector = @"moduleDidRegisterUserNotificationSettings:";

UPModuleManager.h
/* 模塊事件枚舉值 */
typedef NS_ENUM(NSInteger, UPModuleEventType) {
    UPMSetupEvent = 0,
    UPMInitEvent,
    UPMTearDownEvent,
    UPMWillResignActiveEvent,
    UPMDidEnterBackgroundEvent,
    UPMWillEnterForegroundEvent,
    UPMDidBecomeActiveEvent,
    UPMWillTerminateEvent,
    UPMDidReceiveMemoryWarningEvent,
    UPMDidFailToRegisterForRemoteNotificationsEvent,
    UPMDidRegisterForRemoteNotificationsEvent,
    UPMDidReceiveRemoteNotificationEvent,
    UPMDidReceiveLocalNotificationEvent,
    UPMDidRegisterUserNotificationSettings
};

5.進(jìn)入main函數(shù),進(jìn)入U(xiǎn)PAppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    [[UPModuleManager sharedInstance] handleModuleEvent:UPMSetupEvent];
    [[UPModuleManager sharedInstance] handleModuleEvent:UPMInitEvent];
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
    [UNUserNotificationCenter currentNotificationCenter].delegate = self;
#endif
    return YES;
}

6.進(jìn)入處理方法

- (void)handleModuleEvent:(UPModuleEventType)eventType
{
    NSString *selectorName = _moduleEventSelectorInfoDictionary[@(eventType)];
    if (![selectorName isKindOfClass:[NSString class]]) {
        return;
    }
    SEL selector = NSSelectorFromString(selectorName);
    if (!selector) {
        return;
    }
    [self.modules enumerateObjectsUsingBlock:^(id<UPModuleProtocol> moduleInstance, NSUInteger idx, BOOL *_Nonnull stop) {
      if ([moduleInstance respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
          [moduleInstance performSelector:selector
                               withObject:[UPContext sharedInstance]];
#pragma clang diagnostic pop
      }
    }];
}

7.補(bǔ)充協(xié)議內(nèi)容

#import <Foundation/Foundation.h>

@class UPContext;
/**
 * 模塊協(xié)議聲明接口。該接口聲明了做為一個(gè)模塊,都需要時(shí)間的方法。
 */
@protocol UPModuleProtocol <NSObject>

@optional

/**
 * @brief 模塊Setup方法。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 * @discussion 模塊可以在該方法中去進(jìn)一步注冊(cè)其對(duì)外提供的服務(wù)。
 */
- (void)moduleSetup:(UPContext *)context;

/**
 * @brief 模塊初始化方法。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleInit:(UPContext *)context;

/**
 * @brief 模塊銷毀方法。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleTearDown:(UPContext *)context;

/**
 * @brief 當(dāng)App處于非活躍狀態(tài)時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleWillResignActive:(UPContext *)context;

/**
 * @brief 當(dāng)App已經(jīng)進(jìn)入后臺(tái)時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidEnterBackground:(UPContext *)context;

/**
 * @brief 當(dāng)App將要進(jìn)入后臺(tái)時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleWillEnterForeground:(UPContext *)context;

/**
 * @brief 當(dāng)App處于活躍狀態(tài)時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidBecomeActive:(UPContext *)context;

/**
 * @brief 當(dāng)App將要退出時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleWillTerminate:(UPContext *)context;

/**
 * @brief 當(dāng)App收到內(nèi)存告警時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidReceiveMemoryWarning:(UPContext *)context;

/**
 * @brief 當(dāng)App遠(yuǎn)程推送通知注冊(cè)失敗時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidFailToRegisterForRemoteNotifications:(UPContext *)context;

/**
 * @brief 當(dāng)App遠(yuǎn)程推送通知注冊(cè)成功時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidRegisterForRemoteNotifications:(UPContext *)context;

/**
 * @brief 當(dāng)App收到遠(yuǎn)程推送通知時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidReceiveRemoteNotification:(UPContext *)context;

/**
 * @brief 當(dāng)App收到本地通知時(shí),CoreHive通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidReceiveLocalNotification:(UPContext *)context;

/**
 * @brief 當(dāng)App收到application:didRegisterUserNotificationSettings:代理方法時(shí),CoreHive會(huì)通過該方法通知給模塊。
 * @param context 包含CoreHive環(huán)境信息的對(duì)象.
 */
- (void)moduleDidRegisterUserNotificationSettings:(UPContext *)context __OSX_AVAILABLE_STARTING(__MAC_NA, __IPHONE_8_0);

@end

這樣,所有的模塊都在UPAppDelegate中調(diào)度,以UPModuleProtocol為核心,所有遵循此協(xié)議的模塊都可以操作。搭建了項(xiàng)目的根本,包括推送日志登錄等功能,不包括設(shè)備綁定等具體業(yè)務(wù)邏輯。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容