# 基于堆的弹窗管理-iOS **Repository Path**: glue-mobile-components/AlertView-Manager-iOS-Release ## Basic Information - **Project Name**: 基于堆的弹窗管理-iOS - **Description**: 基于堆的弹窗管理-iOS,欢迎提Bug、优化,详见ReadMe - **Primary Language**: Objective-C - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-11-14 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 基于堆的弹窗(AlertView)管理器 ## 一、背景 目前项目上使用自定制的AlertView,但弹窗缺乏管理,在处理某些业务场景时,往往需要额外的代码去处理,不够优雅。举一些的例子: 场景1: > 当前App页面已经存在一个弹窗,用户没有理会,后台无操作一段时间后回到前台,会触发超时弹窗,点击弹窗按钮触发登录逻辑,此时期望清除掉原有页面的弹窗。 场景2: > 登录成功后,根据用户的个人情况(如身份证过期)弹出一些弹窗,同时可能存在一些营销弹窗需要弹出。 ## 二、需求分析 根据目前已知的场景,我们需要设计一个弹窗管理器来统一管理弹窗,其要具备以下能力: - 优先级 - 可清理 - 弹窗与管理器解耦 因为需要对新弹窗进行排序(比较优先级),因此数据结构选择了堆,下面聊下基本思路: 展示:当创建一个`item`(待展示的弹框)后,将其入堆进行维护,比较其与当前展示的`currentItem`的优先级,若优先级高于`currentItem`,则currentItem所代表的item消失,展示`item`,同时`currentItem = item`。 删除:当点击`currentItem `指向的弹窗的按钮后,删除堆中对应的`item`,并维护堆的正确性 ## 三、设计 ### 1.优先级 在创建待展示的弹窗时,我们可以为其配置一个权重值来确定展示的优先级,当权重值相同时,优先展示后入堆的,即: > 优先级 = 综合权重值 = 权重值 + 序列值 ### 2.可清理 依赖于堆的特性,我们可以很方便的清理堆中的元素,考虑到业务场景,我们可以为弹窗配置一个clearOther的选项,当点击该弹窗的按钮时,判断其clearOther,若为true,则清空堆。 ### 3.弹窗与管理器解耦 在写demo时,使用了一个名为[DAlertView](https://github.com/destinyzhao/DAlertView)的简洁的开源弹窗,考虑到在应用时,往往项目都有自己的弹窗样式,因此使用了一个桥接类来实现弹窗与管理器的解耦,避免在做兼容修改时,不小心改动了管理逻辑。 ## 四、实现 本身利用堆的特性来做这个事情思路是比较清晰的,但在实践中,消耗时间最多的是处理线程问题,是的,没错,开发准则要求我们要在子线程处理数据,在主线程更新UI,那么就需要协调两个线程之间的关系,主要原则: - 在子线程维护堆 - 在准备弹窗前挂起子线程,待弹窗展示完毕后,载恢复 - 弹窗准备消失前,阻塞主线程,维护堆,然后恢复主线程。这里牺牲了性能,但是目前没有想到更好的办法去处理快速点击时维护堆产生的错乱