Skip to content

iOS_tutorial_cn

guoling edited this page Apr 24, 2024 · 4 revisions

MMKV for iOS/macOS

MMKV 是基于 mmap 内存映射的 key-value 组件,底层序列化/反序列化使用 protobuf 实现,性能高,稳定性强。从 2015 年中至今在微信上使用,其性能和稳定性经过了时间的验证。近期也已移植到 Android / macOS / Windows / POSIX 平台,一并开源。

使用指南

MMKV 可以直接使用,所有变更立即生效,无需调用 synchronize 之类的函数。

初始化 MMKV

  • 在 App 启动时初始化 MMKV(设定 MMKV 的根目录),例如在-[MyApp application: didFinishLaunchingWithOptions:]里:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // init MMKV in the main thread
        [MMKV initializeMMKV:nil];
    
        //...
        return YES;
    }
  • 如果你需要多进程访问(在主 App 与 Extension 之间),那么需要在初始化时设置 group directory:

    NSString *myGroupID = @"group.company.mmkv";
    // the group dir that can be accessed by App & extensions
    NSString *groupDir = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:myGroupID].path;
    [MMKV initializeMMKV:nil groupDir:groupDir logLevel:MMKVLogInfo];

    注意: 当在 AppExtension 或 WatchExtension 中使用 MMKV 时,你应该使用动态库链接到你的 target (详见安装指南)。

CRUD 操作

  • MMKV 提供一个全局的实例,可以直接使用:

    MMKV* mmkv = [MMKV defaultMMKV];
    
    [mmkv setBool:YES forKey:@"bool"];
    NSLog(@"bool:%d", [mmkv getBoolForKey:@"bool"]);
    
    [mmkv setInt32:-1024 forKey:@"int32"];
    NSLog(@"int32:%d", [mmkv getInt32ForKey:@"int32"]);
    
    [mmkv setInt64:std::numeric_limits<int64_t>::min() forKey:@"int64"];
    NSLog(@"int64:%lld", [mmkv getInt64ForKey:@"int64"]);
    
    [mmkv setFloat:-3.1415926 forKey:@"float"];
    NSLog(@"float:%f", [mmkv getFloatForKey:@"float"]);
    
    [mmkv setString:@"hello, mmkv" forKey:@"string"];
    NSLog(@"string:%@", [mmkv getStringForKey:@"string"]);
    
    [mmkv setDateorKey:@"date"];
    NSLog(@"date:%@", [mmkv getDateForKey:@"date"]);
    
    NSData *data = [@"hello, mmkv again and again" dataUsingEncoding:NSUTF8StringEncoding];
    [mmkv setDataForKey:@"data"];
    data = [mmkv getDataForKey:@"data"];

NSLog(@"data:%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

NSDictionary *dic = @{@"key1" : @"value1",
                      @"key2" : @(2)};
[mmkv setObject:dic forKey:@"dictionary"];
dic = [mmkv getObjectOfClass:[NSDictionary class] forKey:@"dictionary"];
NSLog(@"dictionary:%@", dic);

```

可以看到,MMKV 在使用上还是比较简单的。
  • 删除、枚举

    MMKV *mmkv = [MMKV defaultMMKV];
    
    [mmkv removeValueForKey:@"bool"];
    [mmkv removeValuesForKeys:@[@"int32", @"int64"]];
    
    BOOL hasBool = [mmkv containsKey:@"bool"];
        
    [mmkv enumerateKeys:^(NSString *key, BOOL *stop) {
        if ([key isEqualToString:@"string"]) {
            NSString *value = [mmkv getStringForKey:key];
            NSLog(@"%@ = %@", key, value);
            *stop = YES;
        }
    }];
    
    // delete everything
    [mmkv clearAll];
  • 如果不同业务需要区别存储,也可以单独创建自己的实例:

    MMKV* mmkv = [MMKV mmkvWithID:@"MyID"];
    [mmkv setBool:YES forKey:@"bool"];
  • 如果你需要多进程访问(在主 App 与 Extension 之间),那么如前文所述需要在初始化时设置 group directory。然后传入 MMKVMultiProcess 参数获取多进程实例:

    MMKV *mmkv = [MMKV mmkvWithID:@"MyMultiID" mode:MMKVMultiProcess];
    [mmkv setBool:YES forKey:@"bool"];

支持的数据类型

  • 支持以下 C/C++ 语语言基础类型:
    • bool, int32, int64, uint32, uint64, float, double
  • 支持以下 Objective-C 类型:
    • NSString, NSData, NSDate
  • 支持实现了<NSCoding>协议的任何类型。

NSUserDefaults 迁移

  • MMKV 提供了 -[MMKV migrateFromUserDefaultsDictionaryRepresentation:] 函数,可以比较方便地迁移数据过来。

    auto userDefault = [[NSUserDefaults alloc] initWithSuiteName:@"myDefault"];
    auto mmkv = [MMKV mmkvWithID:@"testImportNSUserDefaults"];
    [mmkv migrateFromUserDefaultsDictionaryRepresentation: userDefault.dictionaryRepresentation];
    // delete keys & values from userDefault when you're done

下一步

Clone this wiki locally