objective-c - 使用 XPC 在 macOS 中实现多进程共享数据库

标签 objective-c database macos cocoa preference

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

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

Current versions of macOS have a great deal of difficulty, and sometimes outright refuse, to update the values in one process with the values set by a second process.

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

To have one process responsible for all of the shared values and the other processes get/set those values via XPC.

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

此外,我想让这个数据库满足 ACID 要求,我怎样才能实现这一点?

最佳答案

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

(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 对象必须是属性列表对象(NSStringNSNumberNSArrayNSDictionaryNSDateNSData、...)。请参阅Preferences and Settings Programming Guide .

关于objective-c - 使用 XPC 在 macOS 中实现多进程共享数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51756142/

相关文章:

ios - 管理多个 UINavigationController 堆栈的最佳实践

objective-c - KVO 产生错误/未收到通知

ios - Cocos2d : Move CCsprite According to Touch

mysql - 如果第一个表中尚不存在给定值,则 SQL 触发器 : Inserting a row in a table after an insert on another table,

MySQL INSERT ...从 1 个表中选择到 2 个表中

c# - 检查 SQL Azure 中数据库是否存在

Python 包含 Lion 上的文件?

python - 导入错误: No module named selenium cronjob Mac

ios - 根据ISOCountryCode获取货币符号和货币代码

swift - 如何以编程方式连接 Swift/MacOS 中的 outlets 和 action