代码之家  ›  专栏  ›  技术社区  ›  Zohar81

用XPC在macOS中实现多进程共享数据库

  •  0
  • Zohar81  · 技术社区  · 7 年前

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

    关于前一个问题,我建议不要使用CFPreferences(和NSUserDefaults),原因如下

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

    或者,我建议使用以下方法:

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

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

    此外,我想使这个数据库满足酸性要求,我如何才能做到这一点?

    1 回复  |  直到 7 年前
        1
  •  1
  •   James Bucanek    7 年前

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

    (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 文件。

    注:因为这是基于 NSUserDefaults ,和 value 对象必须是属性列表对象( NSString , NSNumber , NSArray , NSDictionary , NSDate , NSData , ...). 见 Preferences and Settings Programming Guide .