我现在可以回答我自己的问题:要在 XPC 方法调用的块回复中返回一个对象作为代理,应该同时调用 setInterface:forSelector:argumentIndex:ofReply: 方法:
- 在 XPC 服务的端点中,其中
exportedInterface
声明了
- 在主机中,
remoteObjectInterface
声明了
即,通用代码:
// common (service/host) protocol definition
@protocol Service
@end
@protocol ServiceFactory
-(void)connectToNewService: (void (^)(id<Service>)reply;
@end
在 XPC 服务中:
// Implement the one method in the NSXPCListenerDelegate protocol.
-(BOOL)listener:(NSXPCListener *)listener shouldAcceptNewConnection:(NSXPCConnection*)newConnection {
NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:@protocol(ServiceFactory)];
NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:@protocol(Service)];
// connection has to be returned as proxy, not as a copy
[serviceFactoryInterface setInterface: serviceInterface
forSelector: @selector(connectToNewService:)
argumentIndex: 0
ofReply: YES];
newConnection.exportedInterface = serviceFactoryInterface;
newConnection.exportedObject = self;
[newConnection resume];
return YES;
}
在主机代码中:
// in the host
- (void)openNewService
{
NSXPCConnection *xpcConnection = [[NSXPCConnection alloc] initWithServiceName:@"eu.mycompany.servicefactory"];
NSXPCInterface *serviceFactoryInterface =[NSXPCInterface interfaceWithProtocol:@protocol(ServiceFactory)];
NSXPCInterface *serviceInterface =[NSXPCInterface interfaceWithProtocol:@protocol(Service)];
// connection has to be returned as proxy, not as a copy
[serviceFactoryInterface setInterface: serviceInterface
forSelector: @selector(connectToNewService:)
argumentIndex: 0
ofReply: YES];
xpcConnection.remoteObjectInterface = serviceFactoryInterface;
[xpcConnection resume];
[[xpcConnection remoteObjectProxy] connectToNewService:^(id<Service> newService) {
// here a newService is returned as NSXPCDistantObject <Service>*
[xpcConnection invalidate];
}];
}