0

In my project I am using the C-based XPC API, since NSXPCConnection is not available on the platform I am targeting. Currently I use a weak reference to prevent the connection handler block from retaining self, as follows:

__block VTVoltControllerProxy *proxy = self;

xpc_connection_set_event_handler(_connection, ^(xpc_object_t object) {
    xpc_type_t type = xpc_get_type(object);

    ...

    if (type == XPC_TYPE_ERROR && object == XPC_ERROR_CONNECTION_INVALID) {
        if ([[proxy delegate] respondsToSelector:@selector(voltControllerDidDisconnectFromHost:)]) {
           [[proxy delegate] voltControllerDidDisconnectFromHost:proxy];
        }
    }
});

However, an issue is introduced whenever the connection is cancelled inside the -dealloc method of my class:

- (void)dealloc
{
    ...

    xpc_connection_cancel(_connection);
    xpc_release(_connection);

    ...
}

Because cancelling an XPC connection is an asynchronous operation, the connection handler is called after the class instance has already been deallocated, causing proxy to point to an object that no longer exists.

Is there a way that I can safely cancel the connection in -dealloc and have the connection handler call the delegate method after cancellation?

ProtoSphere
  • 209
  • 3
  • 9

2 Answers2

1

You should be able to change the event handler to point at an event handler which is only used for the purpose of watching that the connection closes. You can either queue the pending connections in another object (perhaps a global or static) or just make the assumption that any connection calling this separate event handler is being called because it is being cancelled (check the event type of course).

gaige
  • 17,263
  • 6
  • 57
  • 68
0

Running into the same problem today. I don't know if you already resolved this or not. But what if dealloc waits for the XPC connection to be closed before continue.

It's possible to introduce a conditional variable to achieve this behavior. But I am wondering what the drawback it could bring.

Negative Zero
  • 1,224
  • 3
  • 10
  • 19