ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

GYBootingProtection 源码全解:deleteAllFilesUnderDocumentsLibraryCaches 修复实现与 Block 回调链设计

GYBootingProtection 源码全解:deleteAllFilesUnderDocumentsLibraryCaches 修复实现与 Block 回调链设计

【免费下载链接】GYBootingProtection

A tool for detecting and repairting continuous launch crash of iOS App

项目地址:https://gitcode.com/gh_mirrors/gy/GYBootingProtection
点击查看免费下载

GYBootingProtection 是一款专门用于iOS App 启动连续闪退(launch continuous crash)检测与自动修复的轻量级开源工具。当 App 在启动后短时间内反复崩溃、用户陷入"一打开就闪退"的死循环时,它能自动计数、提示用户,并通过一键清空本地数据的方式让 App 恢复可用。本文带你完整拆解它的核心源码:闪退计数机制、Block 回调链设计,以及关键修复方法deleteAllFilesUnderDocumentsLibraryCaches的实现细节。

从上图可以看到整个体验闭环:检测到启动闪退(黑屏无法进入)→ 弹出提示让用户自修复 → 修复后 App 正常可用。

源码地图:4 个关键文件先看一遍

想读懂这个项目,只需要看 src/ 目录下的 4 个文件:

文件职责
GYBootingProtection.h公开接口:3 个 Block 类型定义 + 所有类方法声明
GYBootingProtection.m核心实现:启动闪退计数、上报/修复触发、文件删除
AppDelegate+GYBootingProtection.hAppDelegate 分类声明
AppDelegate+GYBootingProtection.mMethod Swizzling 入口、修复弹窗 UI、修复逻辑挂钩

配套还有 CocoaPods 描述文件 GYBootingProtection.podspec(最低支持 iOS 8.0)和可运行的 demo/GYBootingProtectionDemo/ 示例工程。

检测原理:5 秒阈值 + NSUserDefaults 连续闪退计数

连续闪退检测的核心逻辑在 launchContinuousCrashProtect 方法中,由三组常量驱动:

  • kCrashOnLaunchTimeIntervalThreshold = 5.0:启动后 5 秒内 crash 才算"启动闪退";
  • kContinuousCrashOnLaunchNeedToReport = 5:连续闪退达到 5 次,触发上报;
  • kContinuousCrashOnLaunchNeedToFix = 5:连续闪退达到 5 次,触发修复流程。

工作流程可以概括为三步:

  1. App 启动时:从NSUserDefaults读取上一次的crashCount,并立即+1写回。也就是说,"这次启动是否闪退"是在下一次启动时由计数体现的。
  2. 计时保命:通过CACurrentMediaTime()记录启动时刻,再用dispatch_after延迟 5 秒(见 GYBootingProtection.m)。若 App 活过 5 秒说明本次启动成功,计数清零。
  3. 触发修复:当读取到的计数 ≥ 5 时,先执行reportBlock上报,再进入修复流程并置isFixing = YES防止重复修复。

上图为项目自带的整体流程图:正常路径是"计数 +1 → 5 秒后重置计数 → 正常启动流程";异常路径是"提示用户修复 → 进入保护流程(尝试 JSPatch → 修复流程删除 Document Library Caches → 重置计数 → 统计上报)"。

还有一个精巧的细节:检测入口是通过 Method Swizzling 实现的。+load 在运行时把application:didFinishLaunchingWithOptions:与swizzled_application:didFinishLaunchingWithOptions:交换,因此在开发者完全无感知的情况下,每次启动都会先执行闪退保护逻辑(见 swizzled 方法)。

Block 回调链设计:Report、Repair、Completion 三级分工

这是本项目最值得学习的设计。GYBootingProtection.h 中定义了三种 Block:

typedef BOOL (^BoolCompletionBlock)(void); typedef void (^RepairBlock)(BoolCompletionBlock); typedef void (^ReportBlock)(NSInteger crashCounts);

三者构成一条清晰的回调链:

  1. ReportBlock(上报):只负责"连续 crash 了 N 次"的统计上报,不关心修复结果;
  2. RepairBlock(修复):接收一个BoolCompletionBlock作为参数。框架把"修复完成后的收尾工作"(清零计数、取消修复标记)封装进这个 completion,修复方只需专注自己的修复逻辑,完成后回调即可;
  3. BoolCompletionBlock(收尾):无论走修复分支还是正常分支,最终都会执行一次,用于继续执行正常的启动流程。

在 launchContinuousCrashProtect 中可以看到这个嵌套结构:需要修复时调用repairBlock(completion),completion 内部先setCrashCount:0、setIsFixing:NO,再执行用户传入的 completion;不需要修复时则直接执行 completion。这种"框架管状态、业务管逻辑"的分工,让修复逻辑可以同步也可以异步(见 onBootingProtectionWithCompletion:),是典型的控制反转思想。

UI 层的对接同样简洁:showAlertForFixContinuousCrashOnCompletion: 弹出"检测到应用可能已损坏,是否尝试修复?"对话框,用户点"修复"时调用tryToFixContinuousCrash:,点"取消"也会执行 completion——保证回调链只断裂于用户操作,而不会漏掉收尾。

deleteAllFilesUnderDocumentsLibraryCaches 修复实现全解

修复动作之所以能生效,靠的是"重置本地数据到初始状态"。核心方法见 deleteAllFilesUnderDocumentsLibraryCaches,实现分三步:

  1. 定位目录:用NSSearchPathForDirectoriesInDomains分别取出Documents、Library、Caches三个沙盒目录路径;
  2. 逐个删除:对每个目录先fileExistsAtPath判断存在性,再用contentsOfDirectoryAtPath枚举一级子项,逐项调用removeItemAtPath删除。注意它删除的是目录内容而非目录本身,删除后目录依然存在,App 下次启动不会因目录缺失报错;
  3. 日志留痕:每个文件的删除成功/失败都通过NSLog输出,最后汇总打印三个目录的剩余内容,便于排查修复效果。

该方法在 onBootingProtection 中被预留为修复钩子(默认注释状态),业务方可在真正接入时放开,或替换成自己的修复策略(如检查 JSPatch 更新)。这也是该库的设计哲学:框架只负责"何时修","怎么修"交给业务。

⚠️ 需要提醒的是:这个方法会清空用户本地缓存与文档数据,属于"破坏性修复"。生产环境建议结合isFixingCrash标记与用户确认弹窗(项目已内置)谨慎使用。

接入与测试:3 步跑通 Demo

  1. 将 src/ 下所有文件拖入 Xcode 项目(或使用 CocoaPods);
  2. 在 onBeforeBootingProtection 中设置Logger与ReportBlock(上报逻辑);
  3. 在onBootingProtection中写入修复逻辑,如调用deleteAllFilesUnderDocumentsLibraryCaches。

想快速验证效果?打开 demo/GYBootingProtectionDemo/ 示例工程:ViewController 提供了一个 "Make a crash" 按钮,点击即人为制造崩溃;配合setStartupCrashForTest:YES彩蛋开关(见 AppDelegate+GYBootingProtection.m),App 会主动弹窗询问是否制造 crash。重复 5 次闪退后,即可亲眼看到完整的"检测 → 提示 → 修复"闭环。

小结

GYBootingProtection 用不到 400 行源码解决了一个真实现场高频问题:

  • 检测:NSUserDefaults计数 + 5 秒存活阈值,简单可靠;
  • 调度:Report / Repair / Completion 三级 Block 回调链,状态管理与业务逻辑彻底解耦;
  • 修复:deleteAllFilesUnderDocumentsLibraryCaches精准清空三大沙盒目录,把 App 拉回"出厂状态";
  • 无侵入:Method Swizzling 自动接管启动流程,业务代码零改动。

如果你的 iOS App 也在为"用户反馈一打开就闪退"而头疼,这套源码本身就是一份很好的崩溃防护设计参考。

【免费下载链接】GYBootingProtection

A tool for detecting and repairting continuous launch crash of iOS App

项目地址:https://gitcode.com/gh_mirrors/gy/GYBootingProtection
点击查看免费下载
上一篇:如何快速使用NS-USBLoader:Switch游戏管理的完整指南
下一篇:NS-USBLoader:Switch游戏管理的终极跨平台解决方案

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表