我希望能够“真正地”序列化异步方法,例如:
- 发出网络请求
- 显示 UIAlertView
这通常是一项棘手的工作,大多数串行队列示例在 NSBlockOperation 的块中显示“睡眠”。这不起作用,因为只有在回调发生时操作才完成。
我已经尝试通过继承 NSOperation 来实现它,这里是实现中最有趣的部分:
+ (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;
}
这很好用,这是一个演示......
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 但确保它们在后台线程中执行以模拟网络调用。日志内容如下
1...
1
2...
2
这是所希望的。这种方法有什么问题?有什么我应该注意的警告吗?