MMKV icon indicating copy to clipboard operation
MMKV copied to clipboard

iOS端 调用 setObject:forKey 失败原因分析

Open SoftBoys opened this issue 7 months ago • 5 comments

MMKV tag 1.2.10

线上问题描述:

  1. 线上每天有大几千个用户触发写入失败的问题(setObject:forKey),大部分用户都可在重启app时自动修复
  2. 且其中90%的用户并没有触发mmkv初始化异常的报错,
  3. 问题排查分析如下

相关代码如下:

Image

Image

A. 存储失败时上报错误日志

if (!success) {
        NSString *message = [NSString stringWithFormat:@"<MMKV:setObject-forKey> key:<%@> failed", key];
       if (g_handleBlock) {
            g_handleBlock(message);
        }
    }

B. 设备A

Image C. 设备B

Image

辛苦帮忙分析确认下:

  1. 该异常是否是使用MMKV不规范引起的呢?
  2. 有相关优化使用建议吗

SoftBoys avatar May 21 '25 14:05 SoftBoys

Your logs are far from enough for meaningful investigation. You should gather ALL logs from MMKV. I recommend using our xlog for logging.

lingol avatar May 21 '25 15:05 lingol

And your version is way too old. Upgrading to the latest version first.

lingol avatar May 21 '25 15:05 lingol

好的 我们尝试升级到最近版本 试下

SoftBoys avatar May 22 '25 02:05 SoftBoys

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

SoftBoys avatar Jun 17 '25 02:06 SoftBoys

unSecureUnArchiveObjectWithData is called when decoding an object.

lingol avatar Jun 17 '25 06:06 lingol

Any update on this issue?

lingol avatar Jul 14 '25 01:07 lingol

Closed due to inactive.

lingol avatar Jul 16 '25 11:07 lingol

抱歉 最近这段时间没有持续跟进这件事情。

最近一周我们发现异常量上报趋势陡增的问题,以下是最近一个月的上报趋势(7.22-7.27数据可忽略) 7.15新版本发布(MMKV 1.3.5)当时观察近一周的数据,异常率对比之前没太大的改善 Image

异常采集时机有两处:

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] 触发的异常,不确定这种情况是否正常

辛苦帮忙确认下:

  1. 最近这段时间的异常是属于系统不稳定导致的还是MMKV不稳定导致的呢?(未升级MMKV前的版本 最近7天也是有一波高峰)

SoftBoys avatar Aug 05 '25 03:08 SoftBoys

You already know the answer to your question. It's not MMKV.

(未升级MMKV前的版本 最近7天也是有一波高峰)

lingol avatar Aug 05 '25 03:08 lingol

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.

lingol avatar Aug 05 '25 03:08 lingol