2016-08-12 101 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