包装&用NSValue解包

时间:2016-08-12 20:48:48

标签: ios objective-c nserror nsvalue

在我的项目中,我有这样的功能:

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**

2 个答案:

答案 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