【问题标题】:implementing multi-process shared DB in macOS using XPC使用 XPC 在 macOS 中实现多进程共享数据库
【发布时间】:2018-08-08 21:50:24
【问题描述】:

我的目标是开发可以在进程之间共享的健壮、连贯和持久的数据库,只需列出 Windows 注册表。

在上一个问题上,由于以下原因,我建议不要使用 CFPreferences(和 NSUserDefaults)

当前版本的 macOS 有很大的困难,有时甚至完全拒绝用第二个进程设置的值更新一个进程中的值。

另外,我建议使用以下方法:

让一个进程负责所有共享值,而其他进程通过 XPC 获取/设置这些值。

XPC 对我来说很新,但从我目前所读的内容来看,它似乎对每个连接都使用 GCD 队列,所以如果有多个进程要求访问 R/ 的同一个数据库,我该如何保持一致性W 操作(如何强制单线程执行所有队列中的项目)。

此外,我想让这个数据库满足 ACID 要求,我该如何实现?

【问题讨论】:

    标签: objective-c database macos cocoa preference


    【解决方案1】:

    这是我的建议,以及我在应用程序中使用的解决方案。

    (1) 创建一个命名的 XPC 服务。

    如果您需要从多个应用连接您的服务,您需要使用 launchd 命名并注册您的服务应用。

    (XPC 可以很容易地创建仅由您的应用使用的匿名服务,但从其他应用连接会有点棘手。从 Daemons and Services Programming Guide 开始。)

    请注意,在我的解决方案中,我已经在 launchd 注册了一个用户代理,所以这只是继续进行步骤 (2) 的问题。

    (2) 添加 XPC 消息处理程序以获取和设置您要共享的值。

    - (void)queryPreferenceForKey:(NSString*)key withReply:(void(^)(id value))reply
    {
        reply([[NSUserDefaults standardUserDefaults] objectForKey:key]);
    }
    
    - (void)setPreferenceValue:(id)value forKey:(NSString*)key withReply:(void(^)(BOOL changed))reply
    {
        BOOL changed = NO;
        id previous = [[DDUserPreferences standardUserDefaults] objectForKey:key];
        if (!OBJECTS_EQUAL(previous,value))
            {
            [[NSUserDefaults standardUserDefaults] setObject:value forKey:key];
            changed = YES;
            }
        reply(changed);
    }
    

    (3) 没有第 3 步。

    基本上就是这样。 NSUserDefault 类是线程安全的,因此不会出现并发问题,它会自动处理属性值的序列化并将它们与应用程序的持久默认值 .plist 文件同步。

    注意:由于这是基于NSUserDefaultsvalue 对象必须是属性列表对象(NSStringNSNumberNSArrayNSDictionaryNSDateNSData、 ...)。见Preferences and Settings Programming Guide

    【讨论】:

    • 要获得更强大的解决方案,请考虑使用 SQLite 而不是 NSUserDefaults 支持服务。 SQLite 已融入 macOS。
    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-07
    • 2022-08-17
    • 2014-07-17
    相关资源
    最近更新 更多