Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 不理解NSOperationQueue序列_Ios_Objective C_Nsoperation_Nsoperationqueue_Nsblockoperation - Fatal编程技术网

Ios 不理解NSOperationQueue序列

Ios 不理解NSOperationQueue序列,ios,objective-c,nsoperation,nsoperationqueue,nsblockoperation,Ios,Objective C,Nsoperation,Nsoperationqueue,Nsblockoperation,我有一个名为DataFetcher的模型类,它通过web服务获取数据,然后将数据持久化到核心数据存储,然后通过委托方法更新ViewController。以下是不使用NSO操作的正常顺序(正常工作): NSArray *serviceQueryResult = [self queryServiceFor:@"car"]; [self setData:serviceQueryResult]; [self persistData:_data]; [_loadDelegate updateCount:_

我有一个名为DataFetcher的模型类,它通过web服务获取数据,然后将数据持久化到核心数据存储,然后通过委托方法更新ViewController。以下是不使用NSO操作的正常顺序(正常工作):

NSArray *serviceQueryResult = [self queryServiceFor:@"car"];
[self setData:serviceQueryResult];
[self persistData:_data];
[_loadDelegate updateCount:_data.count]; 
[_loadDelegate receivedData:_data];
我需要将web服务调用和数据库更新调用放在后台线程上。我的想法是创建一个NSBlockOperation来进行web服务调用,然后再创建一个NSBlockOperation来进行数据库更新。在数据库更新操作开始之前,web服务操作将完成一个依赖项。以下是我试图实现的代码:

__weak DataFetcher *weakSelf = self;
__block NSArray *serviceQUeryResult;
NSBlockOperation *webServiceOperation = [NSBlockOperation blockOperationWithBlock:^{
    serviceQUeryResult = [weakSelf queryServiceFor:@"mini"];
    [weakSelf setData:serviceQUeryResult];
}];
NSBlockOperation *dbInsertOperation = [NSBlockOperation blockOperationWithBlock:^{
    [weakSelf persistData:serviceQUeryResult];
}];

[webServiceOperation addDependency:dbInsertOperation];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:webServiceOperation];

以这种方式设置时,永远不会调用我的queryServiceFor:方法。我也不确定将两个委托方法调用放在何处,因为它们会更新UI,并且应该在主线程上。过去我曾多次使用GCD,但现在需要NSD操作的一些额外功能。有人能帮忙吗?谢谢

基本问题是,您已声明
webservicecooperation
依赖于
dbInsertOperation
(即,在
dbInsertOperation
完成之前,它不会启动
webservicecooperation
),但您永远不会启动
dbInsertOperation
,因此
webservicecooperation
永远不会运行

  • 如果要使
    dbInsertOperation
    依赖于
    webservicecooperation
    ,则不需要:

    [webServiceOperation addDependency:dbInsertOperation];
    
    相反,您希望:

    [dbInsertOperation addDependency:webServiceOperation];
    
  • 创建此依赖项后,请确保将这两个操作都添加到队列中

    [queue addOperation:webServiceOperation];
    [queue addOperation:dbInsertOperation];
    
    依赖项将确保
    dbInsertOperation
    webservicecooperation
    完成之前不会启动。注意,这假设
    webservicecooperation
    同步执行其块。如果网络请求以异步方式运行,您可能希望将其包装在自己的并发/异步
    NSOperation
    子类中


  • 如果要从这些后台操作更新UI,可以:

    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
        // update the UI here
    }];
    
    或使用GCD,如果需要:

    dispatch_async(dispatch_get_main_queue(), ^{
        // update the UI here
    });
    

    谢谢,我错误地认为依赖项隐式地添加了另一个。谢谢你澄清了这一部分。不过,我还不清楚在哪里打代表电话。因为它们最终会更新UI,所以不能将它们放在队列中,对吗?因此,使用GCD调用主线程非常简单,但在这里,我不确定在何处或如何调用UI更新。@Pheepster关于UI更新,您可以使用GCD将代码分派到主队列,也可以使用操作队列等价物,我在修订的答案中显示了这一点。如果我在操作中,我通常会使用操作队列格式副本,但这两种模式都可以正常工作。它们显示在我文章的顶部,在原始的“工作代码”中,只需在适当的操作中调用它们(如果它们依赖于插入操作,则将它们放在插入操作之后;如果它们仅依赖于web服务调用,则将它们放在插入操作中)。从方法名称中不完全清楚它们在做什么以及逻辑依赖关系是什么,所以我很难更具体地说。但是,如果它们正在更新您的模型对象和/或UI,请确保它们已调度到主队列。