2011-12-13 65 views
0

如何更改下面的代碼與ARC兼容:現在ObjC:間接指針強制轉換成Objective-C的指針

MyObj* fn = nil; 
[self performSelectorOnMainThread:@selector(popSomething:) withObject:(id)&fn waitUntilDone:YES]; 

,我得到以下錯誤:

error: cast of an indirect pointer to an Objective-C pointer to '__strong id' is disallowed with ARC [4]

+0

爲什麼你不能使用'[自performSelectorOnMainThread:@selector(queuedFileNamesPop :) withObject:FN waitUntilDone:YES ];'而不是? –

+0

@AndreyZ:因爲在這次調用返回後,'fn'仍然是'nil'。 – Albert

+0

@Albert:那是因爲fn從零開始。 – MusiGenesis

回答

0

參數的類型應該是(id *),即。指向對象的指針,而不是對象。

但如果你只是想從你需要在主線程上執行方法返回一個值,一個更好的解決方案是使用塊和GCD:

__block id poppedFilename; 
dispatch_sync(dispatch_get_main_queue(), ^{ 
    poppedFilename = [self popFilename]; 
}); 
// do something with the popped file 

這種執行方法-popFilename上主線程,並將結果存儲在poppedFilename中。您必須小心,不要在主線程上調用此方法,因爲它會死鎖。如果你不知道你是否在主線程,你可以使用這樣的事情:

__block id poppedFilename; 
if ([NSThread isMainThread]) { 
    poppedFilename = [self popFilename]; 
} else { 
    dispatch_sync(dispatch_get_main_queue(), ^{ 
     poppedFilename = [self popFilename]; 
    }); 
} 
2

如果你希望主線程來更新字符串,然後更好的方式來做到這一點是使用一個可變的字符串,並簡單地將它傳遞給主線程:

NSMutableString* fn = [NSMutableString string]; 
[self performSelectorOnMainThread:@selector(queuedFileNamesPop:) withObject:fn waitUntilDone:YES]; 

然後主線程可以簡單地更新字符串。

+0

爲什麼這會是更好的方式?有沒有辦法我可以以某種方式將被調用函數('queuedFileNamesPop')中的對象傳遞給被調用者?這個解決方案現在適用於'NSString'的情況。如果我想傳遞其他沒有可變類的對象,該怎麼辦? – Albert

+0

performSelectorOnMainThread不會給你任何返回對象的選項,所以你必須傳入一個地方來放置返回值。另一個選擇是傳遞一個NSMutableArray並讓被調用者把它想要的任何東西放入數組中。 – stevex

+0

是的,我想過使用'NSMutableArray'。但我不確定,那對我來說太過分了。這是通常的做法嗎? – Albert