老谭笔记

利用XPC实现多进程之间的通信

关于多进程之间的通信,之前已经写过一篇文章介绍过NSConnection的用法(用NSConnection实现不同进程间的通信),利用NSConnection,可以直接获取到一个远程的对象,然后调用该对象的方法实现进程间的通信,这样的通信是一种直接的连接,优点在于你可以更自由的调用方法,代码直观,调用方便,但缺点是连接过于紧密,耦合性很强。

OSX10.7以后,cocoa新增加了一种新的技术,就是XPC,它的实现不再通过对象间的直接连接,而是通过block实现一种服务端对客户端的connection,这两者之间的通信都是通过使用xpc_connection发送消息实现。XPC的出现是为了将程序分成不同的几个子程序,从而实现权限分隔,让你的程序更加安全。

XPC在10.8以后,直接在Foundation.framework中添加了NSXPCConnection相关的类,使用更为方便,但在10.7的系统上面,我们就只能使用C的接口来实现(引入头),下面我就通过实际的代码简单的演示一下吧(以下的代码将一个加法计算的业务交由服务端处理,然后将计算结果返回客户端):

服务端的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
static void XPCService_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
{
xpc_type_t type = xpc_get_type(event);
if (type == XPC_TYPE_ERROR)
{
if (event == XPC_ERROR_CONNECTION_INVALID)
{
//连接无效
}
else if (event == XPC_ERROR_TERMINATION_IMMINENT)
{
//即将终止
}
} else
{
//处理业务
double value1 = xpc_dictionary_get_double(event, "value1");
double value2 = xpc_dictionary_get_double(event, "value2");
xpc_object_t dictionary = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_double(dictionary, "result", value1+value2);
xpc_connection_send_message(peer, dictionary);
}
}
static void XPCService_event_handler(xpc_connection_t peer)
{
xpc_connection_set_event_handler(peer, ^(xpc_object_t event) {
XPCService_peer_event_handler(peer, event);
});
xpc_connection_resume(peer);
}
int main(int argc, const char *argv[])
{
xpc_main(XPCService_event_handler);
return 0;
}

客户端的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
const char *connectionName = "com.moft.XPCService.XPCService";
connection = xpc_connection_create(connectionName, NULL);
xpc_connection_set_event_handler(connection, ^(xpc_object_t object){
double result = xpc_dictionary_get_double(object, "result");
NSLog(@"%f",result);
});
xpc_connection_resume(connection);
xpc_object_t dictionary = xpc_dictionary_create(NULL, NULL, 0);
xpc_dictionary_set_double(dictionary, "value1", 1.0);
xpc_dictionary_set_double(dictionary, "value2", 2.0);
xpc_connection_send_message(connection, dictionary);
}

代码下载:XPCTest