从 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 传递非空参数时未调用应用回复的主要内容,如果未能解决你的问题,请参考以下文章