Я использую XPC для разделения проекта на два проекта: основной проект, созданный для os x @ 64-bit, и сервис XPC, созданный для os x @ 32-bit, так как он использует библиотеку, которая недоступна для 32-битный и не может быть заменен. Эти двое общаются с помощью NSXPCConnection.
У меня проблема с обратными вызовами от службы к основному приложению:
когда ответ принимает сложный аргумент (т.е. класс как nsimage или nsdata), он не вызывается из службы xpc. Нет никакой ошибки или исключения, просто ничего не происходит. иногда это происходит и наоборот, т. е. при вызове прокси-объекта. Это происходит не случайно, это происходит только для определенных подписей ответов, хотя я не уверен, какие именно.
Мне нужно каким-то образом передать nsimage между службой xpc и основным приложением. Я попытался передать как NSImage, так и NSData, но ответ не вызывается (стоит упомянуть - он вызывается, когда вместо реального объекта передается nil).
Я попытался отправить указатель, используя [байты NSData], а затем воссоздать данные, используя [NSData initWithData:length:]. Когда я пытаюсь это сделать, вызывается ответ, но я получаю EXC_BAD_ACCESS при вызове initWithData. Я предполагаю, что это из-за некоторой путаницы между 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);
}'
Когда ответ принимает указатель на данные:
экспортированный интерфейс
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);
}