【发布时间】:2015-01-26 07:47:09
【问题描述】:
我在我的应用程序中使用NSOperation 子类,它将在一个操作中执行以下 4 个任务,我希望所有这 4 个任务都在后台线程上运行,所以我将其封装到单个 NSOperation 类中,这样我就可以轻松暂停或取消它
任务
- 长时间运行计算
- 从核心数据中获取数据
- 正在更新到服务器
- 更新核心数据
这里每个都必须同步执行,这意味着除了长时间运行的计算之外,每个都依赖于另一个。
代码
// MyOperation.h
@interface MyOperation : NSOperation {
}
@property (nonatomic, getter = isCancelled) BOOL cancelled;
@end
// MyOperation.m
@implementation MyOperation
- (void)cancel
{
@synchronized (self)
{
if (!self.cancelled)
{
[self willChangeValueForKey:@"isCancelled"];
self.cancelled = YES;
[webServiceOperation cancel]
[self didChangeValueForKey:@"isCancelled"];
}
}
}
- (void)main {
if ([self isCancelled]) {
NSLog(@"** operation cancelled **");
return;
}
@autoreleasepool{
[self performTasks];
}
}
- (void)performTasks {
[self calculate:^{
if (self.isCancelled)
return;
[self fetchDataFromCoredata:^{
if (self.isCancelled)
return;
//I am using AFNetWorking for updateWebService task so it shall run on separate NSOperation so it would be like nested NSOPeration
webServiceOperation = [self updateWebService:^{
if (self.isCancelled)
return;
[self updateCoreData:^{
if (self.isCancelled)
return;
}];
}];
}];
}];
}
@end
我假设我没有遵循正确的方法,因为当我使用 KVO 测试此代码时,NSOperationQueue 在到达计算的完成块之前会收到完整通知。
问题
- 我的方法对吗?
- 如果没有,请您指导我正确的方法吗?
- 如果是正确的方法,那么为什么
NSOPerationQueue在完成块执行之前会收到完成通知?
提前致谢!期待您的回复
【问题讨论】:
-
您正在处理取消,就好像这是异步操作一样,但还没有实现
isAsychronous,也没有执行任何isExecuting或isFinishedKVO。 -
@Rob 问题是:你为什么使用操作? AFNeworking 已经在后台提供了它们。
-
@flexaddicted 为什么操作?将复杂的逻辑很好地封装在独立对象中。控制并发度。管理依赖项。等等。有很多理由使用
NSOperation对象,我不会嫉妒任何想要理解这个非常有用的模式的人。 Re AFNetworking,虽然它并非没有自己的缺陷,但你是对的,它很强大,应该考虑。仅供参考,它仅在基于NSURLConnection的AFHTTPRequestOperationManager内提供操作模式,但不在基于NSURLSession的AFHTTPSessionManager内提供操作模式。 -
@Rob 我的问题是关于抽象的。换句话说,AFNetworking 提供了一个很好的抽象级别。所以,IMO,没有必要将它包装在
NSOperations 中。无论如何,是的。如果 OP 想了解有关使用操作的专业人员,我同意您的评论。 -
@flexaddicted 同意。对不起,我错过了你的意思。是的,当然,不应该重新发明轮子。 AFNetworking 是一个很好的起点。并且 OP 还可以查看
AFURLConnectionOperation的源代码,以了解正确的NSOperation子类实现是什么样的示例(虽然,诚然,这是一个复杂的实现)。
标签: ios objective-c objective-c-blocks nsoperation nsoperationqueue