我知道类似的问题已经被问过几次,但我很难弄清楚如何解决这个特定的问题。到目前为止,我所做的一切都是在主踏板上进行的。我现在发现我需要执行一个需要一些时间的操作,并且我想在操作期间在我的显示器上添加一个 HUD,并在操作完成后将其淡出。
在阅读了很多关于 GCD 的内容(并且变得很困惑)之后,我决定最简单的方法是使用 NSInvocationOperation 调用我的耗时方法并将其添加到新创建的 NSOperationQueue 中。这就是我所拥有的:
[self showLoadingConfirmation]; // puts HUD on screen
// this bit takes a while to draw a large number of dots on a MKMapView
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(timeConsumingOperation:)
object:[self lotsOfDataFromManagedObject]];
// this fades the HUD away and removes it from the superview
[operation setCompletionBlock:^{ [self performSelectorOnMainThread:@selector(fadeConfirmation:) withObject:loadingView waitUntilDone:YES]; }];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
[operationQueue addOperation:operation];
我希望这会显示 HUD,开始在地图上绘制点,然后一旦该操作完成,淡出 HUD。
相反,它会显示 HUD,开始在地图上绘制点,然后在绘制点的同时淡出 HUD。根据我的 NSLogs,在调用该方法以淡化 HUD 之前大约有四分之一秒的延迟。与此同时,点的绘制又持续了几秒钟。
我该怎么做才能让它等到地图上的绘图完成后再消失 HUD?
谢谢
编辑添加:
进行以下更改后,我几乎取得了成功:
NSInvocationOperation *showHud = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(showLoadingConfirmation)
object:nil];
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(timeConsumingOperation:)
object:[self lotsOfDataFromManagedObject]];
NSInvocationOperation *hideHud = [[NSInvocationOperation alloc] initWithTarget:self
selector:@selector(fadeConfirmation:)
object:loadingView];
NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];
NSArray *operations = [NSArray arrayWithObjects:showHud, operation, hideHud, nil];
[operationQueue addOperations:operations waitUntilFinished:YES];
奇怪的是,好像是先调用timeConsumingOperation,再调用showLoadingConfirmation,再调用fadeConfirmation。这是根据我在这些方法中触发的 NSLogs 得出的。
我在屏幕上看到的行为是这样的:绘制点并且地图相应地调整它的缩放(部分时间ConsumingOperation),然后HUD出现在屏幕上,然后什么都没有。所有三个 NSLog 都会立即出现,即使 showLoadingConfirmation 在 timeConsumingOperation 完成之前不会发生,并且 fadeConfirmation 似乎根本没有发生。
这看起来很奇怪,但也似乎暗示有一种方法可以在 timeConsumingOperation 完成时使某些事情发生。
我试着添加这个:
[operationQueue setMaxConcurrentOperationCount:1];
还有这个:
[showHud setQueuePriority:NSOperationQueuePriorityVeryHigh];
[operation setQueuePriority:NSOperationQueuePriorityNormal];
[hideHud setQueuePriority:NSOperationQueuePriorityVeryLow];
但它们似乎没有任何区别。