从 NSXPCConnection 传递非空参数时未调用应用回复

Posted

技术标签:

【中文标题】从 NSXPCConnection 传递非空参数时未调用应用回复【英文标题】:App reply not called when passing non-null parameter from NSXPCConnection 【发布时间】:2014-06-19 14:34:02 【问题描述】:

我正在使用 XPC 将一个项目分成两个项目——一个为 os x @ 64 位构建的主项目,以及一个为 os x @ 32 位构建的 XPC 服务,因为它使用的库是不适用于 32 位且无法替换。两者使用 NSXPCConnection 进行通信。

我对从服务到主应用的回调有问题: 当回复采用复杂的参数(即:作为 nsimage 或 nsdata 的类)时,是否不会从 xpc 服务回调。没有错误或异常,只是没有任何反应。这有时也会以另一种方式发生,即在调用代理对象时。它不是随机发生的,它只发生在某些回复签名中,虽然我不确定是哪个。

我需要在 xpc 服务和主应用程序之间以某种方式传递 nsimage。我尝试同时传递 NSImage 和 NSData,但没有调用回复(值得一提 - 当传递 nil 而不是真实对象时调用它)。

我尝试使用 [NSData bytes] 发送指针,然后使用 [NSData initWithData:length:] 重新创建数据。当我尝试此操作时,会调用回复,但在调用 initWithData 时会收到 EXC_BAD_ACCESS。我认为这是因为 32 位和 64 位寻址之间存在一些混乱。

一些代码示例:

当回复采用 nsimage 时:

导出的界面

- (void)getImageWithReply:(void (^)(NSImage *image))reply;

回复来自

- (void)getImageReply:(void (^)(NSImage *image))reply

    //We always re-render. The responsibility to not re-render when not needed will be passed on.
     [self render]; //updates puts in local var mRenderBuffer the render data
     reply(nil, NO);
     NSImage *image = ... //init image. it is being inited correctly, i know that
     reply(image);

'

当回复将ptr指向数据时:

导出的界面

typedef long long XPC_PTR; //As void* has different sizes in 32/64bit env.
- (void)getRenderBufferWithReply:(void (^)(XPC_PTR ptr, uint size))reply;

回复来自:

- (void)getRenderBufferWithReply:(void (^)(READER_PTR ptr, uint size))reply

    [self render];
    reply((XPC_PTR)[mRenderBuffer bytes], mRenderWidth * mRenderHeight * BYTES_PER_PIXEL, YES);

【问题讨论】:

【参考方案1】:

似乎所有通过连接传递的对象都必须符合 NSSecureCoding 协议,而 NSImage 不符合。

NSData 确实符合这个协议,现在我通过连接传递它(不知道为什么当我之前尝试 NSData 时它不起作用)。我正在使用发送的数据在主进程中创建 NSImage。

事后看来,发送指针的尝试是愚蠢的尝试,因为服务和主应用程序自然运行不同的进程,因此它们被映射到不同的物理内存空间。

【讨论】:

【参考方案2】:

NSImage 确实符合 NSSecureCoding 协议

@interface NSImage : NSObject

所以不知道你的意思是什么?

【讨论】:

以上是关于从 NSXPCConnection 传递非空参数时未调用应用回复的主要内容,如果未能解决你的问题,请参考以下文章

从 XPC 服务创建 NSXPCConnection

使用 NSXPCConnection 时如何同步等待回复块

将套接字与 NSXPCConnection 一起使用

如何通过 ctypes 将(非空)列表从 Python 传递到 C++?

NSXPCConnection 或 XPCKit

混合 NSXPCConnection 和 xpc C API