iphone - performSelectorOnMainThread返回值

时间:2010-07-27 17:14:35

标签: iphone cocoa-touch multithreading

我有以下方法:

- (NSMutableArray *)getElements:(NSString *)theURL;

我想知道是否有办法使用performSelectorOnMainThread调用该方法,以便我可以获得返回值。到目前为止,我已尝试过:

myArray = [object performSelectorOnMainThread:@selector(getElements:)
                                   withObject:url waitUntilDone:YES];

但它不起作用,因为performSelectorOnMainThread返回void。我怎么能解决这个问题?

4 个答案:

答案 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环境中使用过这种技术。