AppDelegate解耦模块化

模块管理

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol RCEAppDelegateService<UIApplicationDelegate>
@required
- (NSString *)serviceName;
@end
@interface RCEAppDelegateServiceManager : NSObject
+ (instancetype)sharedServiceManager;

/**
 注册子模块

 */
- (void)registerService:(id <RCEAppDelegateService>)service;

/**
 子模块是否可以响应消息

 */
- (BOOL)canResponseToSelector:(SEL)aSelector;

/**
 子模块进行消息转发
 */
- (void)submoduleForwardInvocation:(NSInvocation *)invocation;
@end

#import "RCEAppDelegateServiceManager.h"
#import <objc/message.h>
@interface RCEAppDelegateServiceManager()
@property(nonatomic , strong)NSMutableArray<id <RCEAppDelegateService> > *services;
@end
@implementation RCEAppDelegateServiceManager
+(instancetype)sharedServiceManager{
    static dispatch_once_t onceToken;
    static RCEAppDelegateServiceManager *manager = nil;
    dispatch_once(&onceToken, ^{
        manager = [[RCEAppDelegateServiceManager alloc] init];
    });
    return manager;
}
-(instancetype)init{
    if (self = [super init]) {
        self.services = [NSMutableArray array];
    }
    return self;
}
- (void)registerService:(id <RCEAppDelegateService>)service{
    if (!service) {
        return;
    }
    __block BOOL has = NO;
    [self.services enumerateObjectsUsingBlock:^(id<RCEAppDelegateService>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj isKindOfClass:[service class]]) {
            obj = service;
            has = YES;
        }
    }];
    if (!has) {
        [self.services addObject:service];
    }
}
- (BOOL)canResponseToSelector:(SEL)aSelector{
    __block IMP imp = NULL;
    [self.services enumerateObjectsUsingBlock:^(id<RCEAppDelegateService>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if ([obj respondsToSelector:aSelector]) {
            imp = [(id)obj methodForSelector:aSelector];
            NSMethodSignature *signature = [(id)obj methodSignatureForSelector:aSelector];
            if (signature.methodReturnLength > 0 && strcmp(signature.methodReturnType, @encode(BOOL)) != 0) {
                imp = NULL;
            }
            *stop = YES;
        }
    }];
    return imp != NULL && imp != _objc_msgForward;
}
-(NSString *)methodSignature:(NSMethodSignature *)methodSignature{
    NSMutableString *signature = [NSMutableString stringWithFormat:@"%s",methodSignature.methodReturnType?:"v"];
    for (NSInteger i = 0 ; i > methodSignature.numberOfArguments; i ++) {
        const char *type = [methodSignature getArgumentTypeAtIndex:i];
        [signature appendString:[NSString stringWithFormat:@"%s",type]];
    }
    return signature;
}
- (void)submoduleForwardInvocation:(NSInvocation *)invocation{
    SEL selector = invocation.selector;
    NSMethodSignature *signature  = invocation.methodSignature;
    NSInteger length = signature.methodReturnLength;
    void *returnBytes = NULL;
    if (length > 0) {
         returnBytes = alloca(length);
    }
    [self.services enumerateObjectsUsingBlock:^(id<RCEAppDelegateService>  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        if (![obj respondsToSelector:selector]) {
            return ;
        }
        // check
        NSString *targetSignature = [self methodSignature:invocation.methodSignature];
        NSString *submodelSignature = [self methodSignature:[(id)obj methodSignatureForSelector:selector]];
        NSAssert([targetSignature isEqualToString:submodelSignature ],@"method must equal " );
        // submodule to invok
        NSInvocation *invok = [NSInvocation invocationWithMethodSignature:signature];
        NSUInteger argCount = signature.numberOfArguments;
        for (NSInteger i = 0 ; i < argCount; i ++) {
            const char *type = [signature getArgumentTypeAtIndex:i];
            NSUInteger size = 0;
            NSGetSizeAndAlignment(type, &size, NULL);
            void *value = alloca(size);
            // target(self) sel(_cmd)
            [invocation getArgument:&value atIndex:i];
            [invok setArgument:&value atIndex:i];
        }
        invok.selector = selector;
        invok.target = obj;
        [invok invoke];
        if (returnBytes) {
            [invok getReturnValue:returnBytes];
        }
        if (returnBytes) {
            [invocation setReturnValue:returnBytes];
        }
    }];
}
@end

采用宏定义方式, 各模块自己注册即可

#import <UIKit/UIKit.h>
#import "RCEAppDelegateServiceManager.h"

#define RCE_REGISTER_SERVICE_NAME(name) \
+(void)load{\
[[RCEAppDelegateServiceManager sharedServiceManager] registerService:[self new]];\
}\
-(NSString *)serviceName{\
return @#name;\
}

@interface RCEAppDelegate : UIResponder<UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@end

#import "RCEAppDelegate.h"
#import <objc/message.h>

@implementation RCEAppDelegate
- (NSArray<NSString *> *)methods{
    static dispatch_once_t onceToken;
    static NSMutableArray *methodList = nil;
    dispatch_once(&onceToken, ^{
        unsigned int count;
        struct objc_method_description *lists = protocol_copyMethodDescriptionList(@protocol(UIApplicationDelegate), NO, YES, &count);
        methodList = [NSMutableArray array];
        for (NSInteger i = 0; i < count; i ++ ) {
            struct objc_method_description method = lists[i];
            SEL selector = method.name;
            [methodList addObject:NSStringFromSelector(selector)];
        }
    });
    return methodList;
}
-(BOOL)respondsToSelector:(SEL)aSelector{
    IMP imp = [self methodForSelector:aSelector];
    BOOL has = imp != nil && imp !=_objc_msgForward;
    if (!has && [[self methods] containsObject:NSStringFromSelector(aSelector)]) {
        has = [[RCEAppDelegateServiceManager sharedServiceManager] canResponseToSelector:aSelector];
    }
    return has;
}
-(void)forwardInvocation:(NSInvocation *)anInvocation{
    [[RCEAppDelegateServiceManager sharedServiceManager] submoduleForwardInvocation:anInvocation];
}
@end

示例1

#import <Foundation/Foundation.h>
#import "RCEAppDelegate.h"
@interface NotificationService : NSObject<RCEAppDelegateService>

@end

#import "NotificationService.h"

@implementation NotificationService
RCE_REGISTER_SERVICE_NAME(NotificationService);
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    NSLog(@"我是notification");
    return YES;
}
@end

示例2

#import <Foundation/Foundation.h>
#import "RCEAppDelegate.h"
@interface RootWindow : NSObject<RCEAppDelegateService>

@end

#import "RootWindow.h"
#import "ViewController.h"
@implementation RootWindow
RCE_REGISTER_SERVICE_NAME(RootWindow)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    application.delegate.window = window;
    
    ViewController* dvc = [[ViewController alloc] init];
    UINavigationController* nav = [[UINavigationController alloc] initWithRootViewController:dvc];
    window.rootViewController = nav;
    [window makeKeyAndVisible];
    return YES;
}
@end

入口

#import <UIKit/UIKit.h>
#import "RCEAppDelegate.h"
@interface AppDelegate : RCEAppDelegate <UIApplicationDelegate>

@end

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSLog(@"");
    if ([super respondsToSelector:@selector(application:didFinishLaunchingWithOptions:)]) {
        [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    return YES;
}
@end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值