笔记:Target管理与简化版路由机制

2018-10-09  本文已影响0人  靠搬砖活着的程序猿

Target管理

背景

在一些复杂页面的开发过程中,经常会碰见位于最深层次的子View向其所在的控制器中发送消息,这种消息跨层级的处理方式中,常见的处理方式,分别是:

事件的传递过程变成了:
DView -> CView -> BView -> AController
需要写大量的事件传递流程的代码,增加了页面书写的复杂度。

目标

我们期待的正确的处理事件传递的方式是Dview -> AController

方案

我们都了解NSNotificationCenter是一种类似于广播的消息通知机制,能够实现一对一或一对多的通知方式。但是通知的使用场景并不适合在同一页面内,在不同的子View和其所在的控制器之间进行消息传递,但是我们可以实现一个专门用于进行一对一的消息通知机制。

发送事件:

ZH_ActionAdapterSend(@"kLoginControllerLoginAction",@"zhouhui",@"123456");

接收事件:

ZH_ActionAdapterReceive(@"kLoginControllerLoginAction",@selector(loginWithName:password:));

通过使用宏的方式在发送事件时候,可以不限制传递参数的类型和数量,ZH_ActionAdapterSend的第一个参数表示需要发送的事件的名称,从第二个参数开始,表示函数需要的参数。

当我们需要改变事件发生的线程时,只需要修改接收事件的方法如下:

[ZHActionAdapter zh_receiveMessageKey:@“kLoginControllerLoginAction” target:self
                                    queue:[NSOperationQueue mainQueue]
                                 selector:@selector(loginWithName:password:)];

如果使用如下代码方式进行方法的发送,则必须限制接收事件时候的函数的参数格式必须为字典形式,不包含user时:

    // 发送事件
    [ZHActionAdapter zh_sendMessageKey:@"kLoginControllerLoginAction"
                              userInfo:@{@"name": @"zhouhui",
                                        @"pwd" : @"asdfghhj"}];
    // SEL方式接收事件
    [ZHActionAdapter zh_receiveMessageKey:@"kLoginControllerLoginAction" target:self
                                 selector:@selector(loginWithParamter:)];
    
    // Block方式接收事件
    [ZHActionAdapter zh_receiveMessageKey:@"kLoginControllerLoginAction" target:self
                               usingBlock:^(id user, NSDictionary *info) {
                                   NSLog(@"登陆成功");
        
    }];

包含user时候,接收事件函数含有两个参数,第一个参数为事件的发送的user,第二个参数的形类型必须为字典:

// 发送事件
[ZHActionAdapter zh_sendMessageKey:@"kLoginControllerLoginAction"
                                  user:btn
                              userInfo:@{@"name" : @"我就是试试"}];
// 接收事件
[ZHActionAdapter zh_receiveMessageKey:@"kLoginControllerLoginAction"
                                   target:self
                                 selector:@selector(loginWithUser:paramter)];

在target进行释放的时候,全局字典中保存的方法也会进行释放

简化版路由方案

主要用来解决组件之间的通信问题,是一个简化版的路由方案,只讲使用,不讲原理,有兴趣可以直接在文章下方看源码

注册页面的Url

ZHRouteRegister("login://mymy/login", "NextViewController.loginWithParamters:")

注意,参数类型是char类型 没有@符号,第一个参数代表注册的地址,第二个参数的组成形式:控制器名称.注册的方法名(必须为类方法)

通过 zh_getViewControllerWithUrl 这种方法获取的控制器,要求参数必须只能包含一个字典类型的参数,举例说明:

ZHRouteRegister("login://mymy/login", "NextViewController.loginWithParamters:")

@implementation NextViewController

+ (UIViewController *)loginWithParamters:(NSDictionary *)paramter {
    NextViewController *vc = [[NextViewController alloc] init];
    NSLog(@"--%@", vc);
    return vc;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    UIViewController *vc = [[ZHSimpleRouteAdapter shareInstance] zh_getViewControllerWithUrl:@"login://mymy/login?name=123&password=asdaas"];
    NSLog(@"获取到的VC 是 = %@", vc);

}
@end

还可以通过zh_getViewControllerOrderByParamtersWithUrl这种方法获取控制器,这时候要求url中query的参数顺序与函数中参数顺序必须一致,并且参数类型只允许为字符串类型,举例说明:

ZHRouteRegister("login://mymy/login", "NextViewController.loginWithName:password:")

@implementation NextViewController

+ (UIViewController *)loginWithName:(NSString *)name password:(NSString *)password {
    NextViewController *vc = [[NextViewController alloc] init];
    NSLog(@"--%@", vc);
    return vc;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    UIViewController *vc = [[ZHSimpleRouteAdapter shareInstance] zh_getViewControllerOrderByParamtersWithUrl:@"login://mymy/login?name=123&password=asdaas"];
    NSLog(@"获取到的VC 是 = %@", vc);
}
@end

GitHub :https://github.com/lazyBoyDog/ActionAdapter

上一篇下一篇

猜你喜欢

热点阅读