1、背景
原生代码不像前端,可以无感更新,当线上出现致命问题时,如果没有做ABTest或者其他远程配置,往往需要通过发版才能解决,而原生发版需要经过应该市场审核,往往流程长(一般需要12小时,甚至24小时以上)。
2、技术方案
JSPatch方案被AppStore拒了,只能转向寻求二进制化的热更新方案
OCRunner,通过编译二进制补丁,理论上是可以通过AppStore审核(待后续尝试一下)
3、实践步骤
OCRunner
1
git clone --recursive https://github.com/SilverFruity/OCRunner.git
详细介绍可参考:https://github.com/SilverFruity/OCRunner/blob/master/README-CN.md
先制造一段崩溃代码:
1
2
3
4
5
6
7
8
9
10
+ (void)willCrash
{
NSLog(@"TestCrash will crash");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSArray *a = @[];
a[0];
NSLog(@"TestCrash do not crash");
});
}
在调用上述代码后,会崩溃,崩溃日志如下:
1
2
3
4
5
6
7
8
9
10
2025-07-25 09:31:03.097029+0800 PSCPatchModule_Example[13445:1707171] PSCTestCrash will crash
2025-07-25 09:31:04.112481+0800 PSCPatchModule_Example[13445:1707171] PSCTestCrash crashing 1
2025-07-25 09:31:04.112714+0800 PSCPatchModule_Example[13445:1707171] PSCTestCrash crashing 2
2025-07-25 09:31:04.112792+0800 PSCPatchModule_Example[13445:1707171] PSCTestCrash crashing 3
2025-07-25 09:31:04.113585+0800 PSCPatchModule_Example[13445:1707171] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'
*** First throw call stack:
(0x1cb39ed94 0x1c445c3d0 0x1cb4adc94 0x104b584f8 0x1051aa038 0x1051ad1b4 0x1051c3e30 0x1051ba5f8 0x1051ba2dc 0x1cb42dd18 0x1cb40f650 0x1cb4144dc 0x20667435c 0x1cd7a037c 0x1cd79ffe0 0x104b583d4 0x1ea89cdec)
libc++abi: terminating due to uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray'
terminating due to uncaught exception of type NSException
再修复这个代码
1
2
3
4
5
6
7
8
9
10
11
NSLog(@"PSCTestCrash will crash");
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSArray *a = @[];
NSLog(@"PSCTestCrash crashing 1");
NSLog(@"PSCTestCrash crashing 2");
NSLog(@"PSCTestCrash crashing 3");
//去掉崩溃代码后
// a[0];
NSLog(@"PSCTestCrash do not crash");
});
执行编译二进制修复文件:
1
./PatchGenerator -files PSCTestCrash.m -refs Scripts.bundle -output binarypatch
日志输出:
1
2
3
4
5
2025-07-25 09:39:17.113022+0800 PSCPatchModule_Example[13424:1699794] PSCTestCrash will crash
2025-07-25 09:39:18.152015+0800 PSCPatchModule_Example[13424:1699794] PSCTestCrash crashing 1
2025-07-25 09:39:18.152216+0800 PSCPatchModule_Example[13424:1699794] PSCTestCrash crashing 2
2025-07-25 09:39:18.152286+0800 PSCPatchModule_Example[13424:1699794] PSCTestCrash crashing 3
2025-07-25 09:39:18.152352+0800 PSCPatchModule_Example[13424:1699794] PSCTestCrash do not crash
4、Demo
github : https://github.com/Payson-Chen/PSCPatchModule