【发布时间】:2014-02-26 22:27:19
【问题描述】:
我有一个 iOS 应用程序,它使用 NSOperationQueue、NSOperations 和 AFNetworking 2.1.0 来触发对服务器的请求。 -[NSOperation main] 方法类似于:
- (void)main {
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager sharedSessionManager];
[sessionManager GET:@"url"
parameters:nil
success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"Success");
}
failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"Failure");
}
];
}
我注意到,当多个操作被创建并快速连续添加到 NSOperationQueue 时,特定操作的回调永远不会被执行。我潜入 AFNetworking 试图找出原因。我最终进入了-[AFURLSessionManager dataTaskWithRequest:completionHandler],看起来像:
- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];
AFURLSessionManagerTaskDelegate *delegate = [AFURLSessionManagerTaskDelegate delegateForManager:self completionHandler:completionHandler];
[self setDelegate:delegate forTask:dataTask];
return dataTask;
}
我在创建 dataTask 后立即添加了一条日志记录语句:
NSLog(@"Task with id %@ created for %@ on queue %@", @(dataTask.taskIdentifier), request.URL.path, dispatch_get_current_queue());
日志揭示了问题:
2014-02-26 14:11:25.071 App[50094:6a2f] Task with id 15 created for /url1 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:25.071 App[50094:460f] Task with id 16 created for /url2 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:26.274 App[50094:6a2f] Task with id 18 created for /url2 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:26.274 App[50094:6c17] Task with id 17 created for /url1 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:27.546 App[50094:6307] Task with id 20 created for /url2 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:27.546 App[50094:6b17] Task with id 19 created for /url1 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:28.705 App[50094:6b17] Task with id 21 created for /url1 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:28.705 App[50094:6307] Task with id 21 created for /url2 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:32.091 App[50094:6307] Task with id 22 created for /url2 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
2014-02-26 14:11:32.091 App[50094:6b17] Task with id 23 created for /url1 on queue <OS_dispatch_queue: NSOperationQueue 0xc4b8560[0xc4b8ac0]>
请注意,日志中的第四组具有相同的 taskIdentifier,这是 AFNetworking 通过委托将任务与其回调关联起来的。
如果我强制 NSOperations 在主队列上运行,那么我将无法重新创建问题 - taskIdentifier 始终是唯一的。
有没有人见过这样的事情?我是否需要确保 -[NSURLSession dataTaskWithRequest:] 仅在主线程上运行才能避免出现 taskIdentifier 冲突?
【问题讨论】:
标签: ios iphone afnetworking afnetworking-2