草庐IT

iOS组件化组件间跳转通讯入门

江湖闹士 2023-08-04 原文

常见的有三种:
1、URL Scheme
2、CTMediator(Target-Action)
3、Protocol-Class

案例:A页面通过这三种方式跳转B页面


非解耦.png

那么我们需要创建是三个类:Mediator AviewController BviewController

1、URL Scheme

scheme是苹果系统提供的一种供APP之间跳转的机制,用来做组件间跳转也是可行的,这种做法是要全局维护一套scheme和block的映射表,在需要被调用的类(BviewController)中+(void)load方法中注册并实现对应的block,在需要跳转的地方(AviewController)中通过URL来进行跳转并传值
实现:

//********Mediator.h中实现***********
@interface SJMediator : NSObject
//scheme跳转
typedef void(^processBlock)(NSDictionary *params);
+(void)registerScheme:(NSString *)scheme block:(processBlock)block;
+(void)openUrl:(NSString *)url params:(NSDictionary *)params;
@end
//********Mediator.m中实现***********
@implementation SJMediator
//维护的一套全局映射表(字典key:scheme,value:block),全局共用一个,所以使用单例
+ (NSMutableDictionary *)mediatorCache{
    static NSMutableDictionary *cache;
    static dispatch_once_t token;
    dispatch_once(&token, ^{
        cache = [NSMutableDictionary dictionary];
    });
    return cache;
}

//scheme注册,被跳转页面+(void)load中实现
+(void)registerScheme:(NSString *)scheme block:(processBlock)block{
    if (scheme && block) {
        [[[self class] mediatorCache] setObject:block forKey:scheme];
    }
}
//跳转页面实现
+(void)openUrl:(NSString *)url params:(NSDictionary *)params{
    //URL可能需要拆分出scheme进行使用,这里简单直接使用,默认URL就是单纯一个scheme
    processBlock block = [[[self class] mediatorCache] objectForKey:url];
    if (block) {
        block(params);
    }
}
@end
//********BviewController.m中实现***********
+ (void)load{
    [SJMediator registerScheme:@"schemeJump://" block:^(NSDictionary *params) {
        BviewController *vc = [[BviewController alloc] init];
        UINavigationController *nav = params[@"nav"];
        [nav pushViewController:vc animated:YES];
    }];
}
//********AviewController.m中点击跳转方法中实现***********
    NSDictionary *params = @{@"nav":self.navigationController};
    [SJMediator openUrl:@"schemeJump://" params:params];
scheme.png

此种方法的总结:
1、需要维护一套映射表,并且注册方法写在+(void)load方法中,在main函数调用之前会走这个方法,会延长APP的启动时间
2、常驻内存,造成资源消耗
3、看似scheme,实则我们看代码中schemeJump://我们可以随便换一个字符串都可以完成跳转,我们使用scheme是为了跟各端统一。用同一套规范就可以实现后端下发scheme,iOS和安卓两端都可以进行跳转
4、跳转的方式是在被跳转页面的load方法block中实现的,所以需要外部传参告诉跳转方式
5、传参方面通过scheme后面拼字符串形式,局限比较大,例如:schemeJump://?token=3jn23e&ID=01

2、CTMediator(Target-Action)

这种方式运用了苹果的运行时
实现:

//********Mediator.h中实现***********
@interface SJMediator : NSObject
//target-action方式
+ (__kindof UIViewController *)getBvcWithContent:(id)content;
@end
//********Mediator.m中实现***********
+ (__kindof UIViewController *)getBvcWithContent:(id)content{
    Class cls = NSClassFromString(@"BviewController");
    //对应的两个object是方法中的两个入参值,根据performSelector的方法来看,最多只能有两个参数,参数可以是任意类型,所以我们尽可能的用字典等集合类型来传参
    UIViewController *vc = [[cls alloc] performSelector:NSSelectorFromString(@"initWithContent:color:") withObject:content withObject:[UIColor colorWithHexString:@"#FF0088"]];
    return vc;
}
//********AviewController.m中点击跳转方法中实现***********
//通过target-action方式跳转详情页
  UIViewController *vc = [SJMediator getBvcWithContent:@"target-action"];
  [self.navigationController pushViewController:vc animated:YES];
//********BviewController.m中实现***********
BviewController中不需要实现其他额外的任何方法
只需要实现自己的initWithContent:color:方法
target_action.png

此种方法的总结:
1、不会入侵被跳转页面,被跳转页面不需要做任何处理
2、跳转方式由外部跳转方决定
3、硬编码多,对于类名和方法名一定要吻合,否则runtime获取不到类型和方法名就会报错,需要做防护处理
4、不需要维护全局映射表
5、传参方面通过字典传内容也相当多了

3、Protocol-Class

此方法与scheme类似,需要维护一个全局映射表(key:Protoc0l,value:Class)
实现:

//********Mediator.h中实现***********
@protocol BViewControllerProtocol <NSObject>
- (UIViewController *)jumpBvcWithParams:(NSDictionary *_Nullable)params;
@end

@interface SJMediator : NSObject
//protocol协议跳转
+ (void)registerProtocol:(Protocol *)protocol class:(Class)class;
+ (Class)fetchClassForProtocol:(Protocol *)protocol;
@end
//********Mediator.m中实现***********
@implementation SJMediator
+ (NSMutableDictionary *)mediatorCache{
    static NSMutableDictionary *cache;
    static dispatch_once_t token;
    dispatch_once(&token, ^{
        cache = [NSMutableDictionary dictionary];
    });
    return cache;
}
//protocol协议跳转
+ (void)registerProtocol:(Protocol *)protocol class:(Class)class{
    if (protocol && class) {
        [[[self class] mediatorCache] setObject:class forKey:NSStringFromProtocol(protocol)];
    }
}
+ (Class)fetchClassForProtocol:(Protocol *)protocol{
    Class cls = [[[self class] mediatorCache] objectForKey:NSStringFromProtocol(protocol)];
    return cls;
}
@end
//********AviewController.m中点击跳转方法中实现***********
//通过protocol_class方式跳转详情页
   Class cls = [SJMediator fetchClassForProtocol:@protocol(BViewControllerProtocol)];
   NSDictionary *params = @{@"color":@"#550088"};
   [self.navigationController pushViewController:[[cls alloc] jumpBvcWithParams:params] animated:YES];
//********BviewController.h中实现***********
注意:继承BViewControllerProtocol协议
//********BviewController.m中实现***********
+ (void)load{
  //注册
    [SJMediator registerProtocal:@protocol(BViewControllerProtocol) class:[self class]];
}

//实现协议方法,创建本类实例
- (UIViewController *)jumpVCWithParams:(NSDictionary * _Nullable)params {
    NSString *colorStr = params[@"color"];
    UIViewController *vc = [[[self class] alloc] init];
    vc.view.backgroundColor = [UIColor colorWithHexString:colorStr];
    return vc;
}
protocol_class.png

此种方法的总结:
1、需要维护一套全局映射表(跟scheme类似)
2、跳转的方式由跳转方处理
3、多了一层protocol
4、传参方面可以传各种类型

本篇只是作为入门,了解三种方式是怎么实现解耦通讯的,通过案例,其实三种利弊也可以看出来,当然还有比较深层次分析的,看这里->组件化方案

有关iOS组件化组件间跳转通讯入门的更多相关文章

  1. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  2. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  3. Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting - 2

    1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里

  4. LC滤波器设计学习笔记(一)滤波电路入门 - 2

    目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称

  5. 微信小程序开发入门与实战(Behaviors使用) - 2

    @作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors    1、什么是behaviors    2、behaviors的工作方式    3、创建behavior    4、导入并使用behavior    5、behavior中所有可用的节点    6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors    1、什么是behaviorsbehaviors是小程序中,用于实现

  6. 【Java入门】使用Java实现文件夹的遍历 - 2

    遍历文件夹我们通常是使用递归进行操作,这种方式比较简单,也比较容易理解。本文为大家介绍另一种不使用递归的方式,由于没有使用递归,只用到了循环和集合,所以效率更高一些!一、使用递归遍历文件夹整体思路1、使用File封装初始目录,2、打印这个目录3、获取这个目录下所有的子文件和子目录的数组。4、遍历这个数组,取出每个File对象4-1、如果File是否是一个文件,打印4-2、否则就是一个目录,递归调用代码实现publicclassSearchFile{publicstaticvoidmain(String[]args){//初始目录Filedir=newFile("d:/Dev");Datebeg

  7. ES基础入门 - 2

    ES一、简介1、ElasticStackES技术栈:ElasticSearch:存数据+搜索;QL;Kibana:Web可视化平台,分析。LogStash:日志收集,Log4j:产生日志;log.info(xxx)。。。。使用场景:metrics:指标监控…2、基本概念Index(索引)动词:保存(插入)名词:类似MySQL数据库,给数据Type(类型)已废弃,以前类似MySQL的表现在用索引对数据分类Document(文档)真正要保存的一个JSON数据{name:"tcx"}二、入门实战{"name":"DESKTOP-1TSVGKG","cluster_name":"elasticsear

  8. ruby - 为什么不能使用类IO的实例方法noecho? - 2

    print"Enteryourpassword:"pass=STDIN.noecho(&:gets)puts"Yourpasswordis#{pass}!"输出:Enteryourpassword:input.rb:2:in`':undefinedmethod`noecho'for#>(NoMethodError) 最佳答案 一开始require'io/console'后来的Ruby1.9.3 关于ruby-为什么不能使用类IO的实例方法noecho?,我们在StackOverflow上

  9. 区块链入门教程(6)--WeBASE-Front节点前置服务安装 - 2

    文章目录1.任务背景2.任务目标3.相关知识点4.任务实操4.1安装配置JDK4.2启动FISCOBCOS4.3下载解压WeBASE-Front4.4拷贝sdk证书文件4.5启动节点4.6访问节点4.7检查运行状态5.任务总结1.任务背景FISCOBCOS其实是有控制台管理工具,用来对区块链系统进行各种管理操作。但是对于初学者来说,还是可视化界面更友好,本节就来介绍WeBASE管理平台,这是一款微众银行开源的自研区块链中间件平台,可以降低区块链使用的门槛,大幅提高区块链应用的开发效率。微众银行是腾讯牵头设立的民营银行,在国内民营银行里还是比较出名的。微众银行参与FISCOBCOS生态建设,一定

  10. Tcl脚本入门笔记详解(一) - 2

    TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是

随机推荐