我有以下方法:
- (NSMutableArray *)getElements:(NSString *)theURL;
我想知道是否有办法使用performSelectorOnMainThread调用该方法,以便我可以获得返回值。到目前为止,我已尝试过:
myArray = [object performSelectorOnMainThread:@selector(getElements:)
withObject:url waitUntilDone:YES];
但它不起作用,因为performSelectorOnMainThread返回void。我怎么能解决这个问题?
答案 0 :(得分:12)
欢迎来到我的朋友的多线程环境。
您需要将返回值存储在实例变量中,或通过withObject
参数按引用传入对象:
NSMutableDictionary *myDict;
[object performSelectorOnMainThread:@selector(getElements:)
withObject:&myDict waitUntilDone:YES];
您的方法原型现在应该如下所示:
- (void)getElements:(NSMutableDictionary **)objects;
答案 1 :(得分:3)
您无法直接执行此操作,因为正如您所说,该方法返回void。
因此,您必须安排另一种方法来获取值,例如通过传递NSDictionary而不是NSString,并让方法将结果存储在字典中。
答案 2 :(得分:2)
最近必须实施这一点。非常适合向NSObject添加类别,以便所有对象都可以执行此操作:
@implementation NSObject (CallSelectorWithObjectOnMainThread)
- (id)resultFromSelectorOnMainThread:(SEL)selector object:(id)object {
NSMutableDictionary *resultDictionary = [NSMutableDictionary dictionaryWithCapacity:1];
NSMutableDictionary *callDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:resultDictionary, @"ResultDictionary", NSStringFromSelector(selector), @"Selector", nil];
if(object) [callDict setValue:object forKey:@"Object"];
[self performSelectorOnMainThread:@selector(callObject:) withObject:callDict waitUntilDone:YES];
return [resultDictionary objectForKey:@"Result"];
}
- (void)callObject:(NSMutableDictionary *)info {
id result;
SEL selector = NSSelectorFromString([info objectForKey:@"Selector"]);
id object = [info objectForKey:@"Object"];
NSMutableDictionary *resultDictionary = [info objectForKey:@"Dictionary"];
if(object)
result = [self performSelector:selector withObject:object];
else
result = [self performSelector:selector];
if(result)
[resultDictionary setValue:result forKey:@"Result"];
}
@end
答案 3 :(得分:2)
我有异步阻塞调用的通用解决方案,任何线程的返回值,不仅是main。主线程的示例如performSelectorOnMainThread:withObject:waitUntilDone:
__block id result = nil;
NSOperationQueue* targetQueue = [NSOperationQueue* mainQueue];
// targetQueue is main thread, but it may be queue on any thread.
[targetQueue addBlockOperation:^{
// performs on target thread.
result = [someObject someSelector];
}];
// wait until operations on targetQueue will finished.
[targetQueue waitUntilAllOperationsAreFinished];
// result is ready here.
我只在ARC环境中使用过这种技术。