2011-12-13 94 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