简体   繁体   English

一对一执行跨线程功能

[英]Execute cross thread function one by one

I have some special functions in my project, they will execute cross many threads, such as childContext perform block or AFNetwork response block: 我的项目中有一些特殊功能,它们将跨许多线程执行,例如childContext perform块或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
                }];
            }];
        }];
    });
}

Now I want to execute them one by one (including all blocks in function). 现在,我要一个一个地执行它们(包括函数中的所有块)。 After reading a couple of other answers, some of the Apple documentation, I get some answers: 在阅读了一些其他答案,一些Apple文档后,我得到了一些答案:

1. NSRecursiveLock 1. NSRecursiveLock

I can add NSRecursiveLock for each function, but the issue is that I can't lock/unlock cross thread. 我可以为每个函数添加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 2. NSOperation

I can add each function to NSOperationQueue as a NSOperation, and set concurrent operation number to 1, but the issue is that I can't make sure the code in block has been executed even the NSOperation finishes successfully. 我可以将每个函数作为NSOperation添加到NSOperationQueue中,并将并发操作号设置为1,但是问题是,即使NSOperation成功完成,我也无法确保块中的代码已经执行。

3. @synchronized 3. @synchronized

I can add @synchronized, but has same issue as NSOperation 我可以添加@synchronized,但与NSOperation有相同的问题

My suggestion is using NSOperationQueue and Asynchronous NSOperation . 我的建议是使用NSOperationQueueAsynchronous NSOperation

You can make sure operation execute one by one in two ways 您可以确保操作以两种方式一一执行

  • addDependency:
  • Set maxConcurrentOperationCount to 1 maxConcurrentOperationCount设置为1

With Asynchronous NSOperation ,it is you to decide when this Operation is done. 使用Asynchronous NSOperation ,您可以决定何时完成此操作。

For example 例如

-(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.
            }];
        }];
    }];
});
}

How to make an Asynchronous NSOperation ,This is what I usually do,you can also refer it in the document. 如何进行Asynchronous NSOperation ,这是我通常要做的,您也可以在文档中参考它。

  1. Keep two property 保留两个财产

     @interface AsyncOperation (){ BOOL finished; BOOL executing; } 
  2. Use these two property to manage Operation state 使用这两个属性来管理操作状态

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

    3.Mark Operation start 3.标记Operation开始

Note:start function is called on the thread the Operation created 注意:在创建的线程上调用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. Mark Operation is done 标记操作完成

I use this function 我用这个功能

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM