gpt4 book ai didi

objective-c - XPC 没有为收集正确注册类

转载 作者:太空狗 更新时间:2023-10-30 03:32:00 24 4
gpt4 key购买 nike

我在 10.8 上的一个应用程序中使用 XPC。它具有为导出接口(interface)和远程接口(interface)定义的协议(protocol)的标准设置。我遇到的问题是我在导出接口(interface)上的一种方法。

我有一个模型类,我们就称它为 Foo。该类遵循NSSecureCoding,实现+supportsSecureCoding,使用安全编码方式对内部属性进行正确的编码/解码。当通过我的导出接口(interface)上仅涉及单个实例的方法传递此对象时,它工作正常。

当我想传递这些对象的集合,或 Foo 对象的 NSArray 时,就会出现问题。下面是导出接口(interface)上的签名的示例:

- (void)grabSomethingWithCompletion:(void (^)(NSArray *foos))completion;

并且我已将 Foo 类列入白名单,如文档中所述:

NSSet *classes = [NSSet setWithObject:Foo.class];
[exportedInterface setClasses:classes forSelector:@selector(grabSomethingWithCompletion:) argumentIndex:0 ofReply:YES];

现在这应该可以让这个数组可以安全地跨进程复制并在另一端解码。不幸的是,这似乎没有按预期工作。

在导出协议(protocol)上调用方法时,我收到异常:

Warning: Exception caught during decoding of received reply to message 'grabSomethingWithCompletion:', dropping incoming message and calling failure block.

Exception: Exception while decoding argument 1 of invocation: return value: {v} void target: {@?} 0x0 (block) argument 1: {@} 0x0

Exception: value for key 'NS.objects' was of unexpected class 'Foo'. Allowed classes are '{( NSNumber, NSArray, NSDictionary, NSString, NSDate, NSData )}'.

这几乎看起来它甚至没有注册我之前执行的白名单。有什么想法吗?

最佳答案

编辑 2:这取决于您将 Foo 列入白名单的位置。它需要从调用 grabSomethingWithCompletion: 的任何内容中列入白名单。例如,如果您有一个实现和公开的服务:

- (void)takeThese:(NSArray *)bars reply:(void (^)(NSArray *foos))completion;

然后您需要服务端为传入连接将 Bar 列入白名单:

// Bar and whatever Bar contains.
NSSet *incomingClasses = [NSSet setWithObjects:[Bar class], [NSString class], nil];
NSXPCInterface *exposedInterface = [NSXPCInterface interfaceWithProtocol:@protocol(InYourFaceInterface)];
[exposedInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:NO];

// The next line doesn't do anything.
[exposedInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES];
xpcConnection.exposedInterface = exposedInterface;

第二部分必须在连接的另一端继续,无论与您的服务对话是什么:

NSSet *incomingClasses = [NSSet setWithObjects:[Foo class], [NSNumber class], nil];
NSXPCInterface *remoteObjectInterface = [NSXPCInterface interfaceWithProtocol:@protocol(InYourFaceInterface)];
[remoteObjectInterface setClasses:incomingClasses forSelector:@selector(takeThese:reply:) argumentIndex:0 ofReply:YES];
xpcConnection.remoteObjectInterface = remoteObjectInterface;

总而言之,接收奇怪对象的对象必须是将奇怪对象列入白名单的对象。不确定这是否是您的问题,但我敢肯定这是某人的问题。

编辑:现在我使用 XPC 已经有一段时间了,我意识到我的答案虽然解决了一个问题,但并没有解决你的问题。我现在已经遇到过几次不同的情况,但我仍然不确定除了实现我自己的集合类之外如何解决它,这不太理想。

原始答案:我知道你问这个问题已经有一段时间了,但是经过大量搜索却没有人回答这个问题,我想我会发布我的答案来找出造成它的原因(可能还有其他原因,但这解决了它对我来说)。

在符合NSSecureCoding的类中,在initWithCoder:方法中,需要通过传入集合中包含的所有可能类的集合来显式解码集合.前两个是解码的标准例子,最后一个是解码集合:

if (self = [super init]) {
self.bar = [aDecoder decodeInt64ForKey:@"bar"];
self.baz = [aDecoder decodeObjectOfClass:[Baz class] forKey:@"baz"];
NSSet *possibleClasses = [NSSet setWithObjects:[Collection class], [Foo class], nil];
self.foo = [aDecoder decodeObjectOfClasses:possibleClasses forKey:@"foo"];
}

因此,如果您的集合是包含 NSString 的集合,则可能的类将是 [NSSet class][NSString class]

我确定您已经解决了这个问题,但也许其他人和我一样需要这个答案。

关于objective-c - XPC 没有为收集正确注册类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16765421/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com