我最近一直在调试一个带有操作的僵尸问题,并发现在队列上调用cancelAllOperations并没有取消有问题的操作,事实上,即使操作仍在运行,操作队列也是空的。
该结构是一个视图控制器,异步地从Web上加载一组图像并对它们执行一些更改。相关的(匿名的)exerpts如下:
@implementation MyViewController
- (id) init
{
(...)
mOperationQueue = [[NSOperationQueue alloc] init];
(...)
}
- (void) viewDidAppear:(BOOL)animated
{
(...)
MyNSOperation * operation = [[MyNSOperation alloc] initWithDelegate:self andData:data];
[mOperationQueue addOperation:operation];
[operation release];
(...)
}
- (void) dealloc
{
(...)
[mOperationQueue cancelAllOperations];
[mOperationQueue release];
(...)
}
- (void) imagesLoaded:(NSArray *)images
{
(...)
}
有问题的操作:
@implementation MyNSOperation
- (id) initWithDelegate:(id)delegate andData:(NSDictionary *)data
{
self = [super init];
if (self)
{
mDelegate = delegate; // weak reference
mData = [data retain];
(...)
}
return self;
}
- (void) main
{
NSAutoReleasePool * pool = [[NSAutoReleasePool alloc] init];
mImages = [[NSMutableArray alloc] init];
// load and compose images
mAlteredImages = (...)
[self performSelectorOnMainThread:@selector(operationCompleted) withObject:nil waitUntilDone:YES];
[pool release];
}
- (void)operationCompleted
{
if (![self isCancelled])
{
[mDelegate imagesLoaded:mAlteredImages];
}
}
观察到的流程如下:
然而,NSOperationQueue的文档明确指出“操作在完成任务之前一直排队等待”。这看起来像是违约。
我通过保留对操作的引用并手动发送取消来修复崩溃,但我想知道为什么原始方法无法防止进一步的问题。有人可以对此有所了解吗?
提前致谢。
答案 0 :(得分:0)
cancelAllOperations
不会取消已启动的操作。它只通知操作有关该事实并让操作取消它自己,只要它想要。因此,您可以获得加薪条件。继续执行deallocacion,在之后确定操作已取消。