在目标C中序列化异步任务 [英] Serializing asynchronous tasks in objective C

查看:64
本文介绍了在目标C中序列化异步任务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够序列化真正的"异步方法,例如:

I wanted to be able to serialize 'genuinely' async methods, for example:

  • 提出网络请求
  • 显示UIAlertView

这通常是一项棘手的事情,大多数串行队列样本在NSBlockOperation的块中显示休眠".这是行不通的,因为该操作仅在发生回调时才完成.

This is typically a tricky business and most samples of serial queues show a 'sleep' in an NSBlockOperation's block. This doesn't work, because the operation is only complete when the callback happens.

我已经通过子类化NSOperation来实现这一点,这是实现过程中最有趣的部分:

I've had a go at implementing this by subclassing NSOperation, here's the most interesting bits of the implementation:

+ (MYOperation *)operationWithBlock:(CompleteBlock)block
{
    MYOperation *operation = [[MYOperation alloc] init];
    operation.block = block;
    return operation;
}

- (void)start
{
    [self willChangeValueForKey:@"isExecuting"];
    self.executing = YES;
    [self didChangeValueForKey:@"isExecuting"];
    if (self.block) {
        self.block(self);
    }
}

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

- (BOOL)isFinished
{
    return self.finished;
}

- (BOOL) isExecuting
{
    return self.executing;
}

效果很好,这是一个演示...

This works well, here's a demonstration...

NSOperationQueue *q = [[NSOperationQueue alloc] init];
q.maxConcurrentOperationCount = 1;

dispatch_queue_t queue = dispatch_queue_create("1", NULL);
dispatch_queue_t queue2 = dispatch_queue_create("2", NULL);

MYOperation *op = [MYOperation operationWithBlock:^(MYOperation *o) {
    NSLog(@"1...");
    dispatch_async(queue, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"1");
        [o finish]; // this signals we're done
    });
}];

MYOperation *op2 = [MYOperation operationWithBlock:^(MYOperation *o) {
    NSLog(@"2...");
    dispatch_async(queue2, ^{
        [NSThread sleepForTimeInterval:2];
        NSLog(@"2");
        [o finish]; // this signals we're done
    });
}];

[q addOperations:@[op, op2] waitUntilFinished:YES];

[NSThread sleepForTimeInterval:5];

注意,我也使用了sleep,但是确保它们在后台线程中执行以模拟网络调用.日志内容如下

Note, I also used a sleep but made sure these were executing in background thread to simulate a network call. The log reads as follows

1...
1
2...
2

根据需要.这种方法有什么问题?我有什么需要注意的警告吗?

Which is as desired. What is wrong with this approach? Are there any caveats I should be aware of?

推荐答案

乍看起来这是可行的,但是某些部分却缺少了一个适当的" NSOperation子类.

At a first glance this would work, some parts are missing to have a "proper" NSOperation subclass though.

您不应对已取消"状态,应在启动时检查isCancelled,如果返回YES,则不要启动()

You do not cope with the 'cancelled' state, you should check isCancelled in start, and not start if this returns YES ("responding to the cancel command")

isConcurrent方法也需要重写,但为简洁起见,您可能省略了它.

And the isConcurrent method needs to be overridden too, but maybe you omitted that for brevity.

这篇关于在目标C中序列化异步任务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆