iOS端 调用 setObject:forKey 失败原因分析
MMKV tag 1.2.10
线上问题描述:
- 线上每天有大几千个用户触发写入失败的问题(setObject:forKey),大部分用户都可在重启app时自动修复
- 且其中90%的用户并没有触发mmkv初始化异常的报错,
- 问题排查分析如下
相关代码如下:
A. 存储失败时上报错误日志
if (!success) {
NSString *message = [NSString stringWithFormat:@"<MMKV:setObject-forKey> key:<%@> failed", key];
if (g_handleBlock) {
g_handleBlock(message);
}
}
B. 设备A
C. 设备B
辛苦帮忙分析确认下:
- 该异常是否是使用MMKV不规范引起的呢?
- 有相关优化使用建议吗
Your logs are far from enough for meaningful investigation. You should gather ALL logs from MMKV. I recommend using our xlog for logging.
And your version is way too old. Upgrading to the latest version first.
好的 我们尝试升级到最近版本 试下
our app supports at least iOS 12,so we dependency MMKV 1.3.5;During development, an abnormal case of mmkv was discovered, but the write function was normal, and the log is as follows;Should we pay attention to this case
iphone os: 17.2.1 iphone: iPhone 12
[I][2025-06-16 21:11:54.446][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:0
[I][2025-06-16 21:11:54.446][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didBecomeActive]> isInBackground:0
[I][2025-06-16 21:16:56.409][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:1
[I][2025-06-16 21:16:56.409][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didEnterBackground]> isInBackground:1
[I][2025-06-17 09:38:14.267][AppDelegate.m][#00#][I]<MMKV:MMKV_IO.cpp::writeActualSize> [mmkv.default] increase sequence to 93, crc 3700976984, actualSize 176850
[I][2025-06-17 09:38:14.267][AppDelegate.m][#00#][I]<MMKV:MMKV.cpp::sync> MMKV::sync, SyncFlag = 1
[I][2025-06-17 09:38:14.541][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:0
[I][2025-06-17 09:38:14.541][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didBecomeActive]> isInBackground:0
[I][2025-06-17 09:40:58.969][AppDelegate.m][#00#][E]<MMKV:MMKV_OSX.cpp::unSecureUnArchiveObjectWithData> fail to init unarchiver Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)}
[I][2025-06-17 09:41:09.219][AppDelegate.m][#00#][E]<MMKV:MMKV_OSX.cpp::unSecureUnArchiveObjectWithData> fail to init unarchiver Error Domain=NSCocoaErrorDomain Code=4864 "*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)" UserInfo={NSDebugDescription=*** -[NSKeyedUnarchiver _initForReadingFromData:error:throwLegacyExceptions:]: incomprehensible archive (0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)}
[I][2025-06-17 09:50:49.228][AppDelegate.m][#00#][I]<MMKV:MMKV_IO.cpp::writeActualSize> [mmkv.default] increase sequence to 94, crc 1013878126, actualSize 179181
[I][2025-06-17 09:50:49.228][AppDelegate.m][#00#][I]<MMKV:MMKV.cpp::sync> MMKV::sync, SyncFlag = 1
[I][2025-06-17 09:57:11.544][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:0
[I][2025-06-17 09:57:11.544][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didBecomeActive]> isInBackground:0
[I][2025-06-17 10:02:11.805][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:1
[I][2025-06-17 10:02:11.806][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didEnterBackground]> isInBackground:1
[I][2025-06-17 10:02:15.007][AppDelegate.m][#00#][I]<MMKV:MMKV_OSX.cpp::setIsInBackground> g_isInBackground:0
[I][2025-06-17 10:02:15.007][AppDelegate.m][#00#][I]<MMKV:libMMKV.mm::+[MMKV didBecomeActive]> isInBackground:0
[I][2025-06-17 10:02:15.299][AppDelegate.m][#00#][I]<MMKV:MMKV_IO.cpp::writeActualSize> [mmkv.default] increase sequence to 95, crc 2273389267, actualSize 181528
[I][2025-06-17 10:02:15.299][AppDelegate.m][#00#][I]<MMKV:MMKV.cpp::sync> MMKV::sync, SyncFlag = 1
unSecureUnArchiveObjectWithData is called when decoding an object.
Any update on this issue?
Closed due to inactive.
抱歉 最近这段时间没有持续跟进这件事情。
最近一周我们发现异常量上报趋势陡增的问题,以下是最近一个月的上报趋势(7.22-7.27数据可忽略)
7.15新版本发布(MMKV 1.3.5)当时观察近一周的数据,异常率对比之前没太大的改善
异常采集时机有两处:
BOOL success = [_mmkv setObject:value forKey:key];
if (!success) {
NSString *message = [NSString stringWithFormat:@"<MMKV:setObject-forKey> key:<%@> failed", key];
[self logWithLevel:MMKVLogError message:message];
}
#pragma mark - MMKVHandler
- (void)mmkvLogWithLevel:(MMKVLogLevel)level file:(const char *)file line:(int)line func:(const char *)funcname message:(NSString *)message {
// 添加空指针检查
const char *safeFile = file ?: "unknown";
const char *safeFunc = funcname ?: "unknown";
NSString *info = [NSString stringWithFormat:@"<MMKV:%s::%s> %@", safeFile, safeFunc, message ?: @""];
[self logWithLevel:level message:info];
}
收到异常时,xlog日志会记录到本地,同时会上报到异常采集服务一份数据。
分析发现两个问题:大多数情况下 - (void)mmkvLogWithLevel:(MMKVLogLevel)level file:(const char *)file line:(int)line func:(const char *)funcname message:(NSString *)message 方法没有触发异常,而是在 调用 [_mmkv setObject:value forKey:key] 触发的异常,不确定这种情况是否正常
辛苦帮忙确认下:
- 最近这段时间的异常是属于系统不稳定导致的还是MMKV不稳定导致的呢?(未升级MMKV前的版本 最近7天也是有一波高峰)
You already know the answer to your question. It's not MMKV.
(未升级MMKV前的版本 最近7天也是有一波高峰)
I don't quite get why you have to stick with v1.3.5. Last time I checked, MMKV < v2.1.0 supports iOS 12.