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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Correctness AdapterViewChildren Summary: AdapterViews can...
    MarcusMa阅读 8,947评论 0 6
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,242评论 19 139
  • 如何用Facebook graphic api上传视频:http://developers.facebook.co...
    百事小武阅读 3,658评论 1 15
  • Bookmarks 书签栏 入职 华为新员工小百科(刷新时间202003023) - 人才供应知多少 - 3MS知...
    Btrace阅读 1,461评论 0 0
  • 1. 并发队列 + 同步任务 注意是主线程执行,要避免UI堵塞问题 输出:只有一条线程(主线程),所有任务依次有序...
    清無阅读 488评论 0 1