- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对我正在处理的一个项目(Mac OS X 应用程序)有一些架构上的疑问。它基本上由两个元素组成:一个在后台运行的守护程序,收集一些数据,以及一个用于表示收集的数据的查看器。
守护进程应在状态栏中可见(无停靠图标),并包含一个可通过状态栏访问的小菜单。它将数据保存在核心数据存储中。菜单项之一是打开查看器的链接。打开此查看器时,普通 GUI 应用程序应启动,包括停靠图标和菜单栏。打开应用程序本身时也会打开查看器(通过双击图标)。
经过一些实验,我发现实现此功能的最佳方法是创建两个应用程序,一个代表查看器的主应用程序和一个代表守护程序的帮助实用程序。我这样做的原因之一是不可能立即在 LSUIElement 值之间切换以强制守护程序/查看器状态。
现在我对这个架构有一些疑问:
守护程序和查看器应用程序都使用相同的核心数据存储来保存和检索数据。当拥有多线程应用程序时,我知道需要多个 NSManagedObjectContext 对象才能正确同步数据。让多个应用程序同时使用同一个核心数据存储怎么样?这是否可能没有冲突、锁定等风险?如何保证一致性?
守护进程应始终在查看器启动时启动。我通过简单地循环所有打开的进程并检查是否列出了守护程序的包标识符来实现此目的。如果没有,则使用 NSWorkspace
的 launchApplication
启动守护进程。这很好用。现在,当用户退出守护进程时,查看器也应该停止。通知查看者守护进程停止的最佳方式是什么?我可以定期检查事件进程并在守护进程消失时退出查看器,但这听起来有点奇怪。我宁愿选择在查看器即将关闭时发送某种通知。但由于此通知应该在应用程序之间发送和捕获,我不知道哪个简单通知服务可用。有什么想法吗?
该应用程序已被沙盒化,因为它将在 Mac App Store 上分发。使用 NSWorkspace
的 launchApplication
启动应用程序会导致目标应用程序在与源应用程序相同的沙盒环境中运行,我认为这根本不是问题,因为在相同的沙箱感觉更好,而且可能确实如此。但想象一下这种情况:守护进程在登录时自动启动(使用 SMLoginItemSetEnabled
),并且用户双击 Viewer.app。由于守护进程已经在运行(同样,这是通过循环事件进程来检查的),因此它将不会启动。现在我们有守护进程和查看器在不同的沙箱中运行,对吗?这会导致有关首选项、核心数据存储等的任何问题吗?
我想使用 NSUserDefaults
进行基本配置,我可以以某种方式在守护程序和查看器之间交换此数据吗?同样,两个应用程序将具有不同的包标识符。
预先感谢您的帮助,非常感谢!
最佳答案
这个问题没有一个正确的答案,但我的解决方法如下:
Both the daemon and viewer application uses the same core data store to save and retrieve data.
因为不支持在进程之间共享核心数据存储(据我所知),所以我让守护进程公开 XPC Service 。查看器无需打开核心数据存储本身,而是使用 NSXPCConnection
通过守护进程访问数据。
假设查看器在没有守护进程的情况下永远不会运行,它可以使用 SMLoginItemSetEnabled
,就像您在问题中提到的那样,为守护进程注册一个 mach 服务,然后连接到该服务。
有示例代码介绍了设置的详细信息 here在 Apple 网站上(摘要:守护进程需要位于 App.app/Contents/Library/LoginItems/daemon.bundle.id.app
),您可能还想阅读 this blog post讨论了沙箱施加的一些额外要求(摘要:额外确保您的团队 ID 位于守护程序的包标识符中)。
The daemon should always start when the viewer starts.
一切就绪:使用 SMLoginItemSetEnabled
注册守护进程后,当查看器连接到其 XPC 服务时,launchd 将启动它(如果需要)。
Now when the user quits the daemon, the viewer should also stop.
查看者可以使用NSXPCConnection
找出守护进程何时退出。守护进程还可以使用SMLoginItemSetEnabled
在退出之前取消注册,这样它就不会重新启动。
I would like to use
NSUserDefaults
for basic configuration, can I somehow interchange this data between the daemon and the viewer? Again, both applications will have different bundle identifiers.
为此使用套件:
// To read or write:
NSUserDefaults* suiteDefaults = [[NSUserDefaults alloc] initWithSuiteName:@"com.example.app.shared"];
[suiteDefaults setObject:[NSDate date] forKey:@"launchTime"];
// Add the suite to -standardUserDefaults to make reading easier:
NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
[defaults addSuiteNamed:@"com.example.app.shared"];
要使用沙箱,查看器和守护程序必须共享一个应用程序组。您甚至可以使用 KVO 来观察共享 key 的更改。
关于macos - 如何处理有关核心数据、共享首选项和通知的 Mac OS X Helper/Main 应用程序架构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14315048/
我在获取列表项时遇到问题,下面是我的 hibernate 代码,在该代码之后是我的方法..下面是我的 junit 测试。我如何确保查询正确执行,以及如何检查结果是否实际工作..这个查询应该返回几个pi
我正在尝试填充对象 Point 3D 的 vector 。我的应用程序读取一个 csv 文件以通过三个坐标 x、y、z 加载 vector 。我使用 float 类型。这是我的代码。 main.cpp
如果我有一个 DataTemplate(或类似的东西),我可以在 Canvas 中使用非 UIElements 吗?我觉得我以前做过这个,这是可能的,但我想不通。这是一些代码...
何时调用类方法 fetchItems()而不是 getItems() ?有区别吗? fetchImage()对比 getImage()等等... 最佳答案 “获取”通常被认为是一个本地操作,只涉及戳内
我的数组中有多个项目,比如说超过 14 个项目。 如何以这种方式将它们分为 2 个不同的组:前 3 个(#1,2,3)将在数组 A 中,接下来的 4 个(#4,5,6,7)将在数组 B 中,下一个 3
这是我正在解决的问题: Assume that the developers of Myro are developing a new black box function called travel
有一个列表框,里面有一些项目。还有一个带有 3x3 矩阵的网格。用户将拖动一个项目并将其放在网格的一个单元格上。 我发现的大多数示例都是关于从一个列表框拖放到另一个列表框的。但我想放入一个网格单元格。
我是一名优秀的程序员,十分优秀!