利用runtime反射機(jī)制解耦

前言

本文參考了微信讀書團(tuán)隊(duì)的文章,學(xué)習(xí)了runtime反射機(jī)制的強(qiáng)大。具體的demo工程

學(xué)習(xí)過程1

A和B想要通信(比如A想要B模塊的某個(gè)能力),都是通過中間件進(jìn)行調(diào)度,這里起名叫Mediator。Mediator并不會(huì)將A和B的.h文件import進(jìn)來,怎么做到的呢?就是通過runtime的反射機(jī)制。如果B想要A模塊的某個(gè)能力,A只需要在Mediator中開放這樣一個(gè)能力接口,供B通過Mediator進(jìn)行調(diào)用。
具體代碼參考如下:

//  main.m
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "B.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        B *b = [[B alloc] init];
        [b print];
    }
    return 0;
}
//  Mediator.h
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface Mediator : NSObject

- (void)printInBFromA:(NSString *)str;

@end

NS_ASSUME_NONNULL_END
//  Mediator.m
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import "Mediator.h"

@implementation Mediator

- (void)printInBFromA:(NSString *)str {
    Class classA = NSClassFromString(@"A");
    id aInstance = [[classA alloc] init];
    [aInstance performSelector:NSSelectorFromString(@"print:") withObject:str];
}

@end
//  A.h
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface A : NSObject


@end

NS_ASSUME_NONNULL_END
//  A.m
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import "A.h"

@implementation A

- (void)print:(NSString *)str {
    NSLog(@"------> %@",str);
}

@end
//  B.h
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface B : NSObject

- (void)print;

@end

NS_ASSUME_NONNULL_END
//  B.m
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/21.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import "B.h"
#import "Mediator.h"

@implementation B

- (void)print {
    Mediator *mediator = [[Mediator alloc] init];
    [mediator printInBFromA:@"hello"];
}

@end

學(xué)習(xí)過程2

如果說需要傳入的參數(shù)不止2個(gè)(performSelector最多只支持兩個(gè)),我們可以通過dict的形式進(jìn)行傳參數(shù)。

學(xué)習(xí)過程3

如果說Mediator需要提供的接口實(shí)在太多,我們可以通過Category,讓各自提供方的模塊制作Mediator的Category。Category文件依舊放在Mediator所在的模塊中。

//  Mediator+A.h
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/22.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import "Mediator.h"

NS_ASSUME_NONNULL_BEGIN

@interface Mediator (A)

- (void)printInDFromA:(NSString *)bookId count:(NSInteger)bookCount price:(CGFloat)bookPrice;

@end

NS_ASSUME_NONNULL_END
//  Mediator+A.m
//  MediatorProject
//
//  Created by hushunfeng on 2018/12/22.
//  Copyright ? 2018 cmcc. All rights reserved.
//

#import "Mediator+A.h"

@implementation Mediator (A)

- (void)printInDFromA:(NSString *)bookId count:(NSInteger)bookCount price:(CGFloat)bookPrice {
    Class classA = NSClassFromString(@"A");
    id aInstance = [[classA alloc] init];
    NSDictionary *params = @{@"bookId":bookId,@"bookCount":@(bookCount),@"bookPrice":@(bookPrice)};
    [aInstance performSelector:NSSelectorFromString(@"printBook:") withObject:params];

}


@end

過程4

Mediator 每一個(gè)方法里都要寫 runtime 方法,格式是確定的,這是可以抽取出來的。在Mediator中添加如下方法:

- (void)performTarget:(NSString *)targetName action:(NSString *)actionName params:(NSDictionary *)params {
    Class target = NSClassFromString(targetName);
    id targetInstance = [[target alloc] init];
    [targetInstance performSelector:NSSelectorFromString(actionName) withObject:params];
}

最后編輯于
?著作權(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ù)。

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