繁体   English   中英

iOS-在非主线程上以串行方式运行异步操作

[英]iOS - Run async operations in serial manner on non-main thread

- (void) fetchOperation:(NSString *c){
    async_method(c):^{
      NSLog(@"%@ completed.",c);
    }
  }
// call fetchOperation:@"A"
// call fetchOperation:@"B"
// call fetchOperation:@"C"

//Expecting output: A completed, B completed, C Completed.

请注意,我希望在非主线程上进行获取。 它们可能是1到n个fetchOperation调用。 而且,每个fetchOperation调用都可能是由于其他一些用户操作(如用户点击)而发生的。 我尝试了信号量nsoperationQueue,但到目前为止还没有运气。

给函数一个完成处理程序作为其接口的一部分...

- (void)fetchOperation:(NSString *)string completion:(void(^)(void))completion {
    async_method(string):^{
        NSLog(@"%@ completed.",string);
        if (completion) completion();
    }
}

然后将通话嵌套...

[self fetchOperation:@"A" completion:^{
    [self fetchOperation:@"B" completion:^{
        [self fetchOperation:@"C" completion:^{
            NSLog(@"all done");
        }];
    }];
}];

编辑要处理任意一组参数,请创建一个接受数组并递归调用自身的函数...

- (void)manyFetchOperations:(NSArray *)parameters completion:(void(^)(void))completion {
    if (!parameters.count) return completion();
    NSString *nextParam = parameters[0];
    NSArray *remainingParams = [parameters subarrayWithRange:NSMakeRange(1, parameters.count-1)];
    [self fetchOperation:nextParam completion:^{
        [self manyFetchOperations:remainingParams completion:completion];
    }];
}

对其进行如下调用,以达到与嵌套相同的效果。

[self manyFetchOperations:@[@"A", @"B", @"C"] completion:^{}];

您尝试过信号灯的基本想法听起来不错。

我喜欢使用可扩展方法,您可以在其中轻松扩展正在执行的操作量,并在其中传递数组中的所有参数(或其他与操作相关的信息)。

简单易扩展的功能!

- (void)performBatchProcess
{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSArray *attributes = @[@"A", @"B", @"C"];
        NSLog(@"Started all Operations at: %f",CFAbsoluteTimeGetCurrent());
        [self performSelectorWithAttributes:attributes success:^{
            NSLog(@"Finished all Operations");
            NSLog(@"Finished at: %f",CFAbsoluteTimeGetCurrent());
        }];
    });
}

此功能基本上用于按顺序将所有操作排队

- (void)performSelectorWithAttributes:(NSArray<NSString *> *)attributes success:(void (^)())success
{
    for (NSString *attribute in attributes)
    {
        [self performOperationWithAttributeAndWait:attribute];
    }
    success();
}

基本功能包括在此处,其成功块用于停止阻塞队列

- (void)performOperationWithAttributeAndWait:(NSString *)attribute
{
    //create a semaphore
    __block dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    void (^privateFinish)(NSString *attribute) = ^(NSString *attribute) {
        NSLog(@"Finished Process: %@",attribute);
        // Stop blocking our thread and go on :-)
        dispatch_semaphore_signal(semaphore);
    };

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"Started Process: %f",CFAbsoluteTimeGetCurrent());
        [NSThread sleepForTimeInterval:2]; // Simulate a process that takes time
        privateFinish(attribute);
    });
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
}

样本日志,它表明操作现在至少需要2秒钟(使用计时器来模拟过程计算)

2017-03-29 00:05:02.570 asdasd[24376:1836160] Started all Operations at: 512431502.570876
2017-03-29 00:05:02.571 asdasd[24376:1836146] Started Process: 512431502.571429
2017-03-29 00:05:04.598 asdasd[24376:1836146] Finished Process: A
2017-03-29 00:05:04.599 asdasd[24376:1836146] Started Process: 512431504.599392
2017-03-29 00:05:06.673 asdasd[24376:1836146] Finished Process: B
2017-03-29 00:05:06.673 asdasd[24376:1836146] Started Process: 512431506.673433
2017-03-29 00:05:08.673 asdasd[24376:1836146] Finished Process: C
2017-03-29 00:05:08.674 asdasd[24376:1836160] Finished all Operations
2017-03-29 00:05:08.674 asdasd[24376:1836160] Finished at: 512431508.674475

检查出的文档maxconcurrentoperationcount财产的NSOperation

可以同时执行的最大排队操作数。

此属性的默认值为NSOperationQueue默认最大并发操作数

将其设置为1只能一次运行一次。

编辑:

为了确保您等待其他人完成,您应该查看依赖项

此属性包含NSOperation对象的数组。 要将对象添加到此数组,请使用addDependency:方法。 直到其所有相关操作完成执行后,操作对象才可以执行。 操作完成执行后,不会从此依赖项列表中删除操作 您可以使用此列表来跟踪所有相关的操作,包括已经完成执行的操作。 从此列表中删除操作的唯一方法是使用removeDependency:方法。

并根据需要is​Finished addDependency和KVO观察isReady

有关上述属性的更多信息和详细信息的良好来源:

暂无
暂无

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

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