我正在尝试使用CFRunLoopRunInMode()
来避免在[AFHTTPClient getPath:...]
完成块中返回。
我的代码如下:
NSLog(@"start");
__block BOOL someCondition = NO;
AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://domain.com"]];
[client getPath:@"my/path" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"success");
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"async log");
someCondition = YES;
});
while (!someCondition) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.5, YES);
}
NSLog(@"failure");
}];
我希望输出为:
start
async log
failure
但我只得到:
start
CFRunLoopRunInMode()
返回kCFRunLoopRunHandledSource
,但调度队列从不执行提交的块。如果我在完成块之外运行相同的代码,则输出符合预期。
我无法弄清为什么从完成块运行时未处理调度队列。
有人可以说明为什么会这样吗?
答案 0 :(得分:1)
我无法弄清楚为什么从完成块运行时不处理调度队列。
因为您没有“运行”调度队列(没有“运行”调度队列)。你运行了运行循环。调度队列是相关的,但是是另一回事。在串行队列(例如main)上一次只能运行一个块。在块完成之前,不能安排其他块。 GCD没有API来规避这一点。这通常是一件非常好的事情,因为它确保了在runloop操作中并不总是存在的队列操作。
答案 1 :(得分:1)
AFNetwork的成功和失败阻止在主队列中调度,您在故障块中写入的异步块也在主队列中调度。
在故障块完成之前,您的GCD同步块将运行。因为' while'条件永远不会是假的,故障块永远不会完成,永远不会有机会被执行。