逐个执行交叉线程功能

时间:2015-06-11 01:25:12

标签: ios objective-c multithreading

我的项目中有一些特殊功能,它们会执行多个线程,例如childContext执行块或AFNetwork响应块:

(void)my_function {
    dispatch_async(dispatch_get_main_queue(), ^{
        NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
        childContext.parentContext = self.managedObjectContext;
        [childContext performBlock:^{
            [self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
                //Do something
                [childContext performBlock:^{
                    //Do something
                }];
            }];
        }];
    });
}

现在我想逐个执行它们(包括函数中的所有块)。在阅读了一些其他答案,一些Apple文档后,我得到了一些答案:

1。 NSRecursiveLock

我可以为每个函数添加NSRecursiveLock,但问题是我无法锁定/解锁交叉线程。

(void)my_function {
    [MyLock lock];    // Lock here
    dispatch_async(dispatch_get_main_queue(), ^{
        NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
        childContext.parentContext = self.managedObjectContext;
        [childContext performBlock:^{
            [self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
                //Do something
                [childContext performBlock:^{
                    //Do something
                    [MyLock unlock];    //Unlock here
                }];
            }];
        }];
    });
}

2。的NSOperation

我可以将每个函数作为NSOperation添加到NSOperationQueue,并将并发操作号设置为1,但问题是即使NSOperation成功完成,我也无法确保块中的代码是否已执行。

3。 @Synchronized

我可以添加@synchronized,但与NSOperation相同的问题

1 个答案:

答案 0 :(得分:0)

我的建议是使用NSOperationQueueAsynchronous NSOperation

您可以确保操作以两种方式逐个执行

  • addDependency:
  • maxConcurrentOperationCount设为1

使用Asynchronous NSOperation,您可以决定何时完成此操作。

例如

-(void)my_function {
dispatch_async(dispatch_get_main_queue(), ^{
    NSManagedObjectContext *childContext = [[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType] autorelease];
    childContext.parentContext = self.managedObjectContext;
    [childContext performBlock:^{
        [self.operationManager POST:URL parameters:nil block:^(AFHTTPRequestOperation *operation, id responseObject) {
            //Do something
            [childContext performBlock:^{
                //Do something
                //Only mark this NSOperation is done when all task of this function is finished.
            }];
        }];
    }];
});
}

如何制作Asynchronous NSOperation,这是我通常所做的,你也可以在文件中提及。

  1. 保留两个属性

    @interface AsyncOperation (){
        BOOL finished;
        BOOL executing;
    }
    
  2. 使用这两个属性来管理操作状态

    -(BOOL)isFinished{
       return finished;
    }
    -(BOOL)isExecuting{
        return executing;
    }
    

    3.Mark Operation开始

  3. 注意:在操作创建的线程上调用start函数

        -(void)start{
        if ([self isCancelled])
        {
           // Must move the operation to the finished state if it is canceled.
            [self willChangeValueForKey:@"isFinished"];
            finished = NO;
            [self didChangeValueForKey:@"isFinished"];
            return;
        }  
    
         // If the operation is not canceled, begin executing the task.
        [self willChangeValueForKey:@"isExecuting"];
        [NSThread detachNewThreadSelector:@selector(main) toTarget:self    withObject:nil];
        executing = YES;
        [self didChangeValueForKey:@"isExecuting"];
        }
    
    1. 标记操作已完成
    2. 我使用此功能

          -(void)setOperationFinished{
             [self willChangeValueForKey:@"isFinished"];
             [self willChangeValueForKey:@"isExecuting"];
             executing = NO;
             finished = YES;
             [self didChangeValueForKey:@"isExecuting"];
             [self didChangeValueForKey:@"isFinished"]; 
          }