【发布时间】:2012-09-11 12:22:04
【问题描述】:
我使用 NSOperation 的子类通过 Amazon 的 iOS 开发工具包 (v1.3.2) 将大文件上传到 AWS S3。这一切都很好,但一些 beta 测试人员遇到了死锁(iOS 5.1.1)。结果是调度操作的 NSOperationQueue 被阻塞,因为一次只允许一个操作运行。问题是我无法重现该问题,而 Beta 测试人员每次都会遇到此问题。
由于 AWS iOS 开发工具包的工作方式,该操作非常复杂。但是,据我所知,根据我的测试,该问题与 AWS iOS 开发工具包无关。该操作的主要方法粘贴在下面。操作main方法的思路是基于this Stack Overflow question。
- (void)main {
// Operation Should Terminate
_operationShouldTerminate = NO;
// Notify Delegate
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate operation:self isPreparingUploadWithUuid:self.uuid];
});
// Increment Network Activity Count
[self incrementNetworkActivityCount];
// Verify S3 Credentials
[self verifyS3Credentials];
while (!_operationShouldTerminate) {
if ([self isCancelled]) {
_operationShouldTerminate = YES;
} else {
// Create Run Loop
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}
// Decrement Network Activity Count
[self decrementNetworkActivityCount];
NSLog(@"Operation Will Terminate");
}
完成分段上传的方法将布尔值_operationShouldTerminate 设置为YES 以终止操作。那个方法看起来像这样。
- (void)finalizeMultipartUpload {
// Notify Delegate
dispatch_async(dispatch_get_main_queue(), ^{
[self.delegate operation:self didFinishUploadingUploadWithUuid:self.uuid];
});
// Operation Should Terminate
_operationShouldTerminate = YES;
NSLog(@"Finalize Multipart Upload");
}
最终的日志语句被打印到控制台,但是 main 方法中的 while 循环似乎没有退出,因为操作的 main 方法中的最终日志语句没有打印到控制台。结果,调度操作所在的操作队列被阻塞,任何调度的操作都不会执行。
操作的isFinished 方法只返回_operationShouldTerminate,如下所示。
- (BOOL)isFinished {
return _operationShouldTerminate;
}
奇怪的是,while 循环没有退出,更奇怪的是它没有在我自己的任何测试设备(iPhone 3GS、iPad 1 和 iPad 3)上发生。非常感谢任何帮助或指示。
【问题讨论】:
标签: ios multithreading amazon-s3 nsoperation nsoperationqueue