在我的项目中,我有这样的功能:
schema.find({}).exec().then( (objs) => {
// objs[0].name still exists
我需要使用函数performSelector:onThread:withObject:waitUntilDone:在另一个线程上调用此函数,如下所示:
- (void)doSomething:(NSError**)error {
...
}
但是函数参数的类型为[self performSelector:@selector(doSomething:) onThread:anotherThread withObject:??? waitUntilDone:NO];
。我正在考虑从NSError**
到-(void)doSomething:
重构函数NSError**
的参数类型,并将NSValue*
类型作为参数传递。
这意味着,我需要将NSValue*
(类型为&error
)包装成NSError **
并将其作为参数传递,然后再打开它。如何包装&用NSValue
类解包NSError**
?
答案 0 :(得分:0)
我认为您可以使用NSValue
的{{1}}和valueWithPointer:
。但我建议你使用其他东西,比如GCD来异步运行一个块,而不是改变方法的签名以适应pointerValue
的限制:
performSelector
如果你真的想走这条路,this question还有一些关于如何解决这个问题的想法。
答案 1 :(得分:0)
您需要重新考虑解决此问题的方法。你的方法:
- (void)doSomething:(NSError**)error
遵循传递NSError *
变量的地址的标准Objective-C模式,以便该方法可以设置变量以返回错误。
如果您尝试异步调用此方法,无论是在尝试使用performSelector:onThread:withObject:waitUntilDone:
还是使用GCD时(如Felipe Cypriano也建议的那样),您必须小心 - 您传递的地址必须存在为执行异步调用的时间,甚至在您解决之后,您必须弄清楚异步调用何时完成,以便您可以检查它是否已设置变量...
处理这类问题的常用方法是使用async方法在完成时调用的完成块,传递任何结果 - 在您的情况下为NSError *
。例如,您可以编写一个方法:
- (void) doSomethingAsyncAndThen:(void (^)(NSError *))completionBlock
{
dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0),
^{
NSError *error = nil;
[self doSomething:&error];
completionBlock(error);
});
}
并称之为:
[self doSomethingAsyncAndThen:^(NSError *error) { NSLog(@"error: %@", error); }];
虽然你想要做的不仅仅是NSLog
结果。
HTH