笔记:Target管理与简化版路由机制
Target管理
背景
在一些复杂页面的开发过程中,经常会碰见位于最深层次的子View向其所在的控制器中发送消息,这种消息跨层级的处理方式中,常见的处理方式,分别是:
- 通过block回调
- 通过delegate回调
事件的传递过程变成了:
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