iOS | MJRouter 一窺

Typedef

typedef void(^ICBCRouterURLHandler)(NSDictionary * _Nullable params);
typedef id _Nullable(^ICBCRouterURLResultHandler)(NSDictionary * _Nullable params);

URL-Handler way

Register

  • Interface
+ (void)registerUrl: (NSString * _Nonnull)url;
+ (void)registerUrl: (NSString * _Nonnull)url handler: (ICBCRouterURLHandler _Nullable)handler;
+ (void)registerUrl: (NSString * _Nonnull)url resultingHandler: (ICBCRouterURLResultHandler _Nullable)resultHandler;
  • Implementation
+ (void)registerUrl: (NSString * _Nonnull)url{
    [self registerUrl:url handler:nil];
}

+ (void)registerUrl: (NSString * _Nonnull)url handler: (ICBCRouterURLHandler _Nullable)handler{
    if([url length]) {
        [self sharedRouter].urlRoutes[url] = @{
            url: handler ? handler : ^(NSDictionary *_){}
        };
    }
}

+ (void)registerUrl: (NSString * _Nonnull)url resultingHandler: (ICBCRouterURLResultHandler _Nullable)resultHandler{
    if([url length]) {
        [self sharedRouter].urlRoutes[url] = resultHandler ? resultHandler : ^id(NSDictionary *_){ return nil; };
    }
}

Call

  • Interface
+ (void)callUrl: (NSString * _Nonnull)url;
+ (void)callUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params;
+ (id _Nullable)resultingUrl: (NSString * _Nonnull)url  withParams: (NSDictionary * _Nullable)params;
  • Implementation
+ (void)callUrl: (NSString * _Nonnull)url{
    [self callUrl:url withParams:@{}];
}

+ (void)callUrl: (NSString * _Nonnull)url withParams: (NSDictionary * _Nullable)params{
    id handler = [self _handlerForUrl:url];
    ICBCRouterURLHandler urlHandler = (ICBCRouterURLHandler)handler;
    if(urlHandler) {
        return urlHandler(params);
    }
}

+ (id _Nullable)resultingUrl: (NSString * _Nonnull)url  withParams: (NSDictionary * _Nullable)params{
    ICBCRouterURLResultHandler resultHandler = (ICBCRouterURLResultHandler)[self _handlerForUrl:url];
    if(resultHandler) {
        return resultHandler(params);
    }
    return nil;
}

Usage

  • Register
[ICBCRouter registerUrl:kTestUrl resultingHandler:^id _Nullable(NSDictionary * _Nullable params) {
        NSLog(@"params: %@",params);
        return [NSObject new];
    }];
  • Call
id obj = [ICBCRouter resultingUrl:kTestUrl withParams:@{
        @"p1": @1,
        @"p2": @2
    }];
    NSLog(@"%@", obj);

Class-Protocol way

Bind

  • Interface
+ (void)bindProtocol: (Protocol *)protocol forClass: (Class)cls;
+ (Class _Nullable)classForProtocol: (Protocol *)protocol;
+ (id _Nullable)instanceForProtocol: (Protocol *)protocol;
  • Implementation
+ (void)bindProtocol: (Protocol *)protocol forClass: (Class)cls{
    if(![self classForProtocol:protocol]) {
        id clsName = NSStringFromClass(cls);
        id protName = NSStringFromProtocol(protocol);
        NSMutableArray *prots = [self sharedRouter].classRoutes[clsName] ?: @[].mutableCopy;
        [prots addObject:protName];
        [self sharedRouter].classRoutes[clsName] = prots;
    }
}

+ (Class _Nullable)classForProtocol: (Protocol *)protocol{
    id protName = NSStringFromProtocol(protocol);
    __block id foundClassName = nil;
    [[self sharedRouter].classRoutes enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull clsName, NSMutableArray *prots, BOOL * _Nonnull stop) {
        NSPredicate *pre = [NSPredicate predicateWithFormat:@"SELF = %@",protName];
        if([prots filteredArrayUsingPredicate:pre].firstObject) {
            foundClassName = clsName;
            *stop = YES;
        }
    }];
    return foundClassName ? NSClassFromString(foundClassName) : nil;
}

+ (id _Nullable)instanceForProtocol: (Protocol *)protocol{
    Class cls = [self classForProtocol:protocol];
    return cls ? [cls new] : nil;
}

Usage

  • TestProtocol
@protocol TestProtocol <NSObject>
- (void)test;
@end
  • ViewController
@interface ViewController ()<TestProtocol>
@end
@implementation ViewController
- (void)test {
    NSLog(@"%s",__func__);
}
@end
  • Bind
    [ICBCRouter bindProtocol:@protocol(TestProtocol) forClass:self.class];
  • Invoke
NSObject<TestProtocol> *s = [ICBCRouter instanceForProtocol:@protocol(TestProtocol)];
if(s) {
    [s test];
}

Innerdef

API disable

- (instancetype)init UNAVAILABLE_ATTRIBUTE;
- (instancetype)new UNAVAILABLE_ATTRIBUTE;

Init & Properties

@property(nonatomic, strong)NSMutableDictionary *urlRoutes;
@property(nonatomic, strong)NSMutableDictionary *classRoutes;

- (instancetype)init
{
    self = [super init];
    if (self) {
        _urlRoutes = @{}.mutableCopy;
        _classRoutes = @{}.mutableCopy;
    }
    return self;
}

Singleton

+ (instancetype)sharedRouter {
    static dispatch_once_t onceToken;
    static ICBCRouter *obj = nil;
    dispatch_once(&onceToken, ^{
        obj = [self new];
    });
    return obj;
}

Reference

?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa閱讀 9,067評(píng)論 0 6
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,695評(píng)論 19 139
  • 如何用Facebook graphic api上傳視頻:http://developers.facebook.co...
    百事小武閱讀 3,812評(píng)論 1 15
  • Bookmarks 書簽欄 入職 華為新員工小百科(刷新時(shí)間202003023) - 人才供應(yīng)知多少 - 3MS知...
    Btrace閱讀 1,734評(píng)論 0 0
  • 1. 并發(fā)隊(duì)列 + 同步任務(wù) 注意是主線程執(zhí)行,要避免UI堵塞問題 輸出:只有一條線程(主線程),所有任務(wù)依次有序...
    清無閱讀 675評(píng)論 0 1

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