Ответ приложения не вызывается при передаче ненулевого параметра из NSXPCConnection

Я использую 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);
}

person Niv    schedule 19.06.2014    source источник


Ответы (2)


Похоже, что все объекты, передаваемые через соединение, должны соответствовать протоколу NSSecureCoding, которому не соответствует NSImage.

NSData соответствует этому протоколу, и теперь я передаю его через соединение (не знаю, почему это не сработало, когда я пробовал NSData ранее). Я создаю NSImage в основном процессе, используя отправленные данные.

Попытка отправить указатель в ретроспективе была глупой попыткой, поскольку служба и основное приложение, естественно, запускают разные процессы и поэтому они отображаются в разные области физической памяти.

person Niv    schedule 19.06.2014

NSImage соответствует протоколу NSSecureCoding.

@интерфейс NSImage : NSObject

Так что не уверен, что вы имеете в виду?

person MobileMe    schedule 16.04.2015