怎么才算完成一个网站,网站的建设费用,在线动画手机网站模板下载,wordpress 分享可见最近在做短视频相关的模块#xff0c;于是在看 GPUImage 的源码。其实有一定了解的伙伴一定知道 GPUImage 是通过 addTarget 链条的形式添加每一个环节。在对于这样的设计赞叹之余#xff0c;想到了实际开发场景下可以用到的场景#xff0c;借此分享。 我们的项目中应该有很… 最近在做短视频相关的模块于是在看 GPUImage 的源码。其实有一定了解的伙伴一定知道 GPUImage 是通过 addTarget 链条的形式添加每一个环节。在对于这样的设计赞叹之余想到了实际开发场景下可以用到的场景借此分享。 我们的项目中应该有很多的聚合页每个聚合页上都有 feed 流而在很多的项目中 feed 流的场景都是可以进行复用的。而在这样的场景下我们希望复用的 feed 流中的 cell 可以在多个界面上进行复用。但是如果每一个 cell 上又有几个点击事件如果每一个 Controller 上都有一堆的事件处理代码又会代码冗余量巨大。 开发中遇到的痛点 随便举个例子微博的信息流微博很多业务都是这样的界面进行展示如果每个 cell 的点击事件代理回 controller 中进行执行那 controller 有多重可想而知... 而且一旦以后业务调整某些跳转页面更改波及的页面之广也是无法接受的。 这个时候就会想可不可以在一个地方固定的处理这些事件 一些解决方案 我记得对于这个问题 源神 曾经提出过 self-manager 的概念可以解决类似的问题。在源神的解决方案中feed 按钮的功能相对单一这样的方式是一种较好的方案但是 feed 上的按钮根据业务场景做不一样的跳转这样的处理又该如何处理呢 其实对于源神的方案其实传入枚举对它做对应的处理就可以了。 还是用微博进行举例现在我们有A,B,C三条业务线都会对会有 feed 展示这个 cell。 A 业务线要求就是要求底部 tabbar 是转发评论和点赞的功能B 业务线的要求是转发的按钮是跳转到业务线 A 评论按钮的点击事件跳转到业务线C点赞按钮的功能保留C 业务线的要求是转发的按钮跳转到业务线 B 评论的按钮保留原功能点赞的按钮跳转到业务线 B 这样的操作。对于这样的恶心要求不要觉得我天马行空我真的遇到过这类似的业务场景而且也确实有对应的需要如果此时还是使用 self-manager来对状态进行判断。可能伪代码的结构大致如下。 typedef NS_ENUM(NSInteger,BusinessLineType){BusinessLineTypeA 0,BusinessLineTypeB,BusinessLineTypeC,
}typedef NS_ENUM(NSInteger,CommentBtnHandleType){CommentHandleTypeA 0,CommentHandleTypeB,CommentHandleTypeC,
}......-(viod)configureCellWithBusiness:(BusinessLineType)businessType{//根据 businseeType 进行判断 将评论点击事件的枚举传入下一级 然后正确响应点击事件//根据 businseeType 进行判断 将转发按钮事件根据业务线枚举讲点击枚举传入下一级...}
复制代码 不知道大家对于这样的代码看到后的感受是怎么样的但是我可以设想到在没有足够的文档说明的情况下如果组里来了一个新的小伙伴或者让一个对当前业务场景不足够熟悉的小伙伴进行维护一定很抓狂感觉这样的形式在维护上的成本还是比较高的。所以这样的方案还是比较适合处理业务上职责比较单一的小块。 此外对于大厂可能有一条业务线的业务代码需要使用到多个产品中的情况这样的方案一样也就不再适用了。因为 view 层承接了业务。 而两个产品的设计并不相同但是业务的逻辑是相同的这个时候就不是简单的替换 view 层就能完成功能添加那么简单的问题了。 ###曾经的方案 基于上边的复杂业务可读性差和让业务和 view 完全解耦的思路这个时候就需要思考是不是有更好的处理方案。在一开始我们的项目出现这样的需求的时候我想到的解决方案是创建一个事件处理中心的概念。 就是将 cell 中的每一个试图需要响应事件回调到 cell 层然后 cell 中有一个 delegate 创建一个叫 HandleEventCenter 的对象controller 创建数组维护来起到回调中心的作用。 这样对于上边的需求我们的处理方案就会变得更加灵活可以写一个通用处理一般场景下的基类然后根据业务线的不同继承自基类重写需要特殊处理的基类的问题。 这是看下这样处理的优缺点 解决了 view 层和业务代码之间代码耦合的问题同时事件的处理不需要在每个 controller 上写多次。同时可以较好的应对点击事件在不同业务线处理不同逻辑的问题而且代码的可读性问题也得到了解决。 问题就在源神提到的我们要将事件一层层向上回调写了很多坨看上去很不爽的回调代码的问题无论 delegate 还是 block 都不够优雅 更好的处理方案 看到 GPUImage 的源码之后我当时想到的方式就是用这种事件链条的形式将事件传递下去就行了。其实在日常开发中我们都习惯了使用 delegate 或者 block 两种方式对事件向上进行传递但是忘记了系统很常用的的 target - action 模式。 下边来看下我们曾经固有模式和现在解决方案的区别。 曾经的方案我们捕捉到事件执行 - 传给上一层(block 或者 代理的模式) - 再上一层 - 最后的代理中心 - 事件响应 现在的解决方案将事件代理中心 - 传递给 cell 层 - 传递给各个事件层 - 在事件执行处调用处理中心对应的方法 这样每层一大堆恶心代码问题得到了解决也完全抽离了试图和业务之间的耦合性。除此之外如果我们的 cell 上添加了新的响应事件不需要在层层响应只需要在处理中心添加新的代理然后再执行处 target 调用对应方法即可。感觉很大程度上减少了代码量同时降低了维护成本。 一些题外话 其实我们在实际的开发中发现一些特殊的场景下事件处理中心的方案存在很大的弊端。比如 我们的界面上有一个编辑功能的按钮按钮点击后我们会跳转到一个新的界面对 cell 的数据源进行修改这个时候再返回我们需要根据新的数据源刷新当前的 cell 。 事件处理中心的处理方案就不足以解决这样复杂的问题否则就需要和 tableView 产生耦合。当然这样的问题我们取巧的进行了解决本文就不进行介绍了。 提这样的题外话不过是想表达每一种方案中可能或多或少的都存在各种各样的问题但是针对问题我们总是可以找到更好的解决方案。总是思考着我们的程序也终究会变得更好。 当然本文中提到的方案也可能存在各种各样的问题希望不吝赐教希望在探讨中找到更平衡的方案。共同进步~~~ 最后 之前看源码一直关注点都在于技术的细节和如何解决问题上。但是经此发现在读源码的过程中真的可以思考那些优秀的开源的代码为什么这样设计在我们日常开发中这样的设计是不是可以得到推广和应用。我相信在这一过程中不知不觉大家都会获得足够的成长和收获~~~