我有一个名为getCount:
的异步方法,该方法转到网址,计算一些内容,并在完成后调用一个回调。
我有另一个同步的方法,需要获取这些结果,将它们放入消息中,然后返回该消息。以下是两者:
- (NSString *)describe {
__block bool gotCount = NO;
[self getCount:^(int count) {
NSLog(@"Got the count: %i", count);
_count = count; // _count is an ivar of the object with this method.
gotCount = YES;
}];
// Pause here until the count has been fetched.
while (!gotCount) {
[NSThread sleepForTimeInterval:0.05];
}
return [NSString stringWithFormat:@"The count is %i", _count];
}
当我尝试这个时,我的回调永远不会被调用。它从不打印
Got the count 0
或此方案中的任何其他值。
如果我注释掉while循环,则会打印出该消息。所以我知道getCount:
方法有效,我的循环等待它到达时出现了问题。
我需要getCount:
保持异步(在其他更重要的地方使用它)我需要describe
保持同步。我怎么处理这个?
答案 0 :(得分:2)
一个可能的事情:如果你的describe方法在主线程中,那么你也从主线程调用getCount方法,所有web回调都在主线程中。 但你用线程睡眠阻止主线程 - >你不能从网上回电来计算。
编辑:
尝试从另一个线程调用getCount方法。使用例如
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self getCount:^(int count) {
NSLog(@"Got the count: %i", count);
_count = count; // _count is an ivar of the object with this method.
gotCount = YES;
}];
});
编辑2:
我尝试了这段代码并且工作正常 - >你的getCount方法中的线程可能有问题。
- (NSString *)describe {
__block bool gotCount = NO;
__block NSInteger _count;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[NSThread sleepForTimeInterval:5.00];
_count = 5;
gotCount = YES;
});
// Pause here until the count has been fetched.
while (!gotCount) {
[NSThread sleepForTimeInterval:0.05];
}
return [NSString stringWithFormat:@"The count is %li", _count];
}
答案 1 :(得分:0)
一种方法可行但是QUITE the hack(苹果公司一直在mac上使用旧苹果)将在等待时运行runloop:
注意:这依赖于与describe方法
在同一队列上的回调请参阅:JSON async request [相同问题]
一个自包含的工作示例:
#import <Foundation/Foundation.h>
@interface T : NSObject
- (NSString *)describe;
@end
@implementation T {
int _count;
}
- (void)getCount:(void (^)(int c)) handler {
dispatch_async(dispatch_get_global_queue(0,0), ^ {
sleep(5);
dispatch_sync(dispatch_get_main_queue(), ^{
handler(55);
});
});
}
- (NSString *)describe {
__block bool gotCount = NO;
[self getCount:^(int count) {
NSLog(@"Got the count: %i", count);
_count = count; // _count is an ivar of the object with this method.
gotCount = YES;
}];
// Pause here until the count has been fetched.
while (!gotCount) {
[[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
}
return [NSString stringWithFormat:@"The count is %i", _count];
}
@end
int main(int argc, char *argv[]) {
@autoreleasepool {
T *t = [T new];
NSLog(@"describe: %@", [t describe]);
}
}