2016-08-12 52 views
0

解开在我的项目,我有这样的功能:包裹及与NSValue

- (void)doSomething:(NSError**)error { 
... 
} 

我需要使用功能performSelector:onThread:withObject:waitUntilDone:,像这样来调用另一个线程此功能:

[self performSelector:@selector(doSomething:) onThread:anotherThread withObject:??? waitUntilDone:NO]; 

但功能参数类型为NSError**。我正在考虑重构功能-(void)doSomething:的参数类型从NSError**NSValue*并通过NSValue*类型作为参数。

这意味着,我需要包裹&error(其为NSError **类型)转换成NSValue并将其传递作为参数,以后解开它。如何包装&解开NSError**NSValue类?

+1

为什么你需要将'NSError'包装在'NSValue'中? – rmaddy

+0

我想包装'NSError **'并传递包装的NSValue作为段,然后调用performSelector:withObject, –

+1

1)为什么你需要用'NSValue'封装NSError',以便将它传递给'performSelector :withObject:'?没有必要包装它。 2)为什么你需要使用'performSelector:withObject:'?总是有比这更好的方法。我建议用更具体的细节来更新你的问题,说明你真正需要做什么,这样人们可以提供更好的建议。 – rmaddy

回答

0

我认为你可以使用NSValuevalueWithPointer:pointerValue。不过,我会建议你使用别的东西,比如GCD运行块异步,而不是改变你的方法的签名以适应performSelector局限性:

dispatch_async(anotherQueue, ^{ 
    [self doSomething:&error]; 
}); 

而且this question对如何处理这个问题,如果多了一些想法你真的想要走这条路。

+0

谢谢,但我需要使用'otherThread'变量,所以,我需要使用performSelector:onThread:WithObject –

0

您需要重新考虑对待此问题的方法。您的方法:

- (void)doSomething:(NSError**)error 

如下传递一个NSError *变量的地址,使得该方法可以设置变量返回误差的标准Objective-C的图案。

如果您试图以异步方式调用此方法,您是否尝试或使用GCD(如Felipe Cypriano也建议)与performSelector:onThread:withObject:waitUntilDone:一起调用,您必须小心 - 您传递的地址的变量必须以异步调用被执行,甚至在你解决之后,你必须弄清异步调用何时完成,以便检查它是否设置了变量...

处理类似问题的常用方法是使用异步方法在完成时调用的完成块,传递任何结果 - 在您的情况下为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