1

我对 NSOperation 有点陌生。我有一个可能需要长时间运行的现有应用程序。该任务通过 Web 服务下载数据。这项任务可能需要一些时间才能完成,尤其是在连接速度较慢的农村地区。我们需要更新这个应用程序,以便用户可以取消下载,或者它可以自行超时。

目前我们正在使用 GCD 执行下载,但无法取消 GCD 操作。下载数据的类最好不要被修改,而只是被视为任何长时间运行的操作。该对象的初始化程序获取 Web 服务数据并在完成时返回。

我不确定是使用 NSInvocationOperation 还是 NSOperation 的子类。该任务非常简单,只是为了允许取消操作。

MBProgressHUD 用作活动指示器,并具有将使用的手势识别器,因此用户可以点击它来取消操作。此外,该操作应提供超时。操作完成后将更改 UI。

当前 GCD 代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0),^{
    // long running operation        
    GaugeList *rg = [[GaugeList alloc] initWithStationInfo:[station id] forHistoryInHours:48 inThisFormat:nil]; 

    dispatch_async(dispatch_get_main_queue(), ^{
        UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
        GaugeViewController *vc = [sb instantiateViewControllerWithIdentifier:@"GaugeDetailViewController"];
        [vc setRiverGauge:rg];
        [self.navigationController pushViewController:vc animated:YES];
        [hud removeFromSuperview];
    });

我正在寻找一个快速的解决方案,但我见过的大多数示例都很冗长,可能需要大量重构。谁能指出一个提供解决方案的例子?谢谢!});

4

1 回答 1

1

NSInvocationOperation不支持取消。它只是让您能够在操作队列上执行现有方法。如果你想取消,你必须写一个NSOperation子类。但是,取消支持确实需要您做一些工作,因为在子类的-main方法中NSOperation(您将长时间运行的工作放在哪里),您需要不断检查isCancelled属性以确定何时从方法返回并结束操作(即。如果您忽略该isCancelled标志并且代码-main继续运行,则取消将无效)。

所以本质上,你想创建一个NSOperation带有委托的子类,你可以调用一个方法(在主队列上)来通知长时间运行的后台操作已经完成,然后让你的长时间运行的代码定期-main检查-isCancelled确保您快速响应取消。

像这样的东西:

@protocol MyOperationDelegate <NSObject>
@required
- (void)myOperationDidComplete:(MyOperation *)operation;
@end

@interface MyOperation : NSOperation
@property (nonatomic, assign) id<MyOperationDelegate> delegate
@end

@implementation MyOperation

- (void)main {
    @autoreleasepool {
        // Long running work
        // Regularly check -isCancelled throughout the work, like this:
        if ([self isCancelled]) {
             // Cleanup
             return;
        }
        // At the end of the work
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.delegate myOperationDidComplete:self];
        });
    }
}

@end
于 2014-01-03T20:09:04.087 回答