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

#macos #nsimage #xpc #nsxpcconnection

#macos #nsimage #xpc #nsxpcconnection

Вопрос:

Я использую XPC для разделения проекта на два проекта — основной проект, созданный для os x @ 64-разрядная версия, и служба XPC, созданная для os x @ 32-разрядная версия, поскольку она использует библиотеку, которая недоступна для 32-разрядной версии и не может быть заменена. Они обмениваются данными с помощью NSXPCConnection.

У меня проблема с обратными вызовами из службы в основное приложение:
когда ответ принимает сложный аргумент (т.Е. Класс как nsimage или nsdata), он не вызывается из службы xpc. Ошибки или исключения нет, просто ничего не происходит. иногда это происходит и другим способом, то есть при вызове прокси-объекта. Это происходит не случайно, это происходит только для определенных подписей ответа, хотя я не уверен, какие именно.

Мне нужно каким-то образом передать nsimage между службой xpc и основным приложением. Я попытался передать как NSImage, так и NSData, но ответ не вызывается (стоит упомянуть — он вызывается, когда передается nil вместо реального объекта).

Я попытался отправить указатель, используя [байты NSData], а затем воссоздать данные, используя [NSData initWithData:длина:] . Когда я пытаюсь это сделать, вызывается ответ, но я получаю 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);

}'
  

Когда ответ принимает 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

Итак, не уверен, к чему вы клоните?