iOS-模組解耦

weixin_33716557發表於2018-04-16

最初在網上看到相關內容,是蘑菇街元件化相關討論。(Limboy(文章1 文章2) 和 Casa (文章))。
但是我大家討論的內容應該是如何解耦吧,而不是元件化本身,只不過解耦是元件化的前提而已。
我現在理解的有兩種方案:

一、中介軟體+runtime

//Mediator.m
@implementation Mediator
+ (UIViewController *)BookDetailComponent_viewController:(NSString *)bookId {
 Class cls = NSClassFromString(@"BookDetailComponent");
 return [cls performSelector:NSSelectorFromString(@"detailViewController:") withObject:@{@"bookId":bookId}];
}
+ (UIViewController *)ReviewComponent_viewController:(NSString *)bookId type:(NSInteger)type {
 Class cls = NSClassFromString(@"ReviewComponent");
 return [cls performSelector:NSSelectorFromString(@"reviewViewController:") withObject:@{@"bookId":bookId, @"type": @(type)}];
}
@end

當然直接這樣寫,元件(模組)多了以後,這個中介軟體將會變的異常龐大,所以可以通過category方式分離元件介面程式碼。這裡有個文章具體講解了細節實現,增加了通過 target-action 簡化寫法。

二、URL+Block

中介軟體提供方法,可以將url和block進行繫結,各元件都要首先呼叫註冊方法,把自己的功能(block)和對應的url註冊到中介軟體中,才能讓其他元件通過url呼叫。
一個簡化的實現:

//Mediator.m 中介軟體
@implementation Mediator
typedef void (^componentBlock) (id param);
@property (nonatomic, storng) NSMutableDictionary *cache
- (void)registerURLPattern:(NSString *)urlPattern toHandler:(componentBlock)blk {
 [cache setObject:blk forKey:urlPattern];
}

- (void)openURL:(NSString *)url withParam:(id)param {
 componentBlock blk = [cache objectForKey:url];
 if (blk) blk(param);
}
@end
//BookDetailComponent 元件
#import "Mediator.h"
#import "WRBookDetailViewController.h"
+ (void)initComponent {
 [[Mediator sharedInstance] registerURLPattern:@"weread://bookDetail" toHandler:^(NSDictionary *param) {
 WRBookDetailViewController *detailVC = [[WRBookDetailViewController alloc] initWithBookId:param[@"bookId"]];
 [[UIApplication sharedApplication].keyWindow.rootViewController.navigationController pushViewController:detailVC animated:YES];
 }];
}
//WRReadingViewController.m 呼叫者
//ReadingViewController.m
#import "Mediator.h"

+ (void)gotoDetail:(NSString *)bookId {
 [[Mediator sharedInstance] openURL:@"weread://bookDetail" withParam:@{@"bookId": bookId}];
}

方案2最大的問題就是每個元件都需要初始化,記憶體裡需要儲存一份表,元件多了會有記憶體問題。

參考:iOS 元件化方案探索

相關文章