gpt4 book ai didi

ios - NSOperationQueue在完成 block 成功时添加新操作

转载 作者:行者123 更新时间:2023-12-01 17:51:02 25 4
gpt4 key购买 nike

我试图在后台线程上以串行顺序完成一些操作。

我正在调用的函数已经有一个完成块,所以当函数完成时,我想用一个新的参数调用相同的函数。

所以基本上是连续的操作。
dispatch_asyncDISPATCH_QUEUE_SERIAL,以正确的顺序触发函数,但是在调用下一个函数之前并不关心第一个函数是否已完成,因此我不想使用它们。
NSOperationQueue* serialQ = [[NSOperationQueue alloc] init];
serialQ.maxConcurrentOperationCount = 1;
对我来说更有意义。因此,当第一个函数开始计算时,队列上的第二个函数必须等待直到完成其完成块。

NSOperationQueue* serialQ = [[NSOperationQueue alloc] init];
serialQ.maxConcurrentOperationCount = 1; //this will set this queue to Serial



for (File *file in queueArrray) {
Streamer *streamer=[[Streamer alloc] init];

NSBlockOperation *downloadOperation = [[NSBlockOperation alloc] init];

__weak NSBlockOperation *weakDownloadOperation = downloadOperation;

[weakDownloadOperation addExecutionBlock:^{
[streamer loadFile:file withCallback:^(NSString *error, BOOL success) {
if (success) {
NSLog(@"file loaded %@",file.fileUrl);
//here start the next operation !!!!!!!!
??????????????????????????????????????
}
}];
}];
}

最佳答案

串行队列实际情况可确保添加到队列中要执行的第一个块在第二个块执行之前已完成。

-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
[self countTo100];
});

dispatch_async(serialQueue, ^{
[self countFrom200To400];
});

dispatch_async(serialQueue, ^{
[self countFrom400To500];
});

}

- (void)countTo100
{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
}

- (void)countFrom200To400
{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
}

- (void)countFrom400To500
{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
}

如果您从上方查看日志,它将先从0 .. 100开始,然后从200 .. 400和400 .. 500开始顺序打印。

现在,考虑以下代码片段,在其中您可以在并发块中执行每个方法,例如:
-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);

dispatch_async(serialQueue, ^{
[self countTo100];
});

dispatch_async(serialQueue, ^{
[self countFrom200To400];
});

dispatch_async(serialQueue, ^{
[self countFrom400To500];
});

}

- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
});

}

- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
});
}

- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
});
}

在这里,您在串行队列中添加了所有方法,但是方法本身在并发块中运行。因此,在这种情况下,结果是随机的。您也可以像这样使用dispatch_group序列化它,
-(void)testSerialQueue
{
dispatch_queue_t serialQueue = dispatch_queue_create("com.serial.queue", DISPATCH_QUEUE_SERIAL);

self.group = dispatch_group_create();

dispatch_async(serialQueue, ^{
[self countTo100];
});

dispatch_async(serialQueue, ^{
[self countFrom200To400];

});

dispatch_async(serialQueue, ^{
[self countFrom400To500];
});
}

- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}

- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);

});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

在这里,您将再次看到它按顺序打印日志。因此,dispatch_group用于序列化并发操作。您可能希望此时删除serialQueue中的dispatch_async。

现在,操作队列让我们看一个简单的例子,
-(void)testSerialQueue
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;

NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];

[operation1 addExecutionBlock:^{
[self countTo100];
}];

[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];

[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}

- (void)countTo100
{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
}

- (void)countFrom200To400
{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
}

- (void)countFrom400To500
{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
}

将count方法添加到NSOperationQueue中,并将maxConcurrentOperation设置为'1',这现在更像是串行队列。每种方法都不会产生其他一些队列,因此,计数是在同一串行队列上执行的。因此,它们都按顺序打印。

现在,让我们看一个模拟您的案例的示例。
-(void)testSerialQueue
{
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
queue.maxConcurrentOperationCount = 1;

NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];

[operation1 addExecutionBlock:^{
[self countTo100];
}];

[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];

[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}

- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
});

}

- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
});
}

- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
});
}

在这种用例中,您将操作添加到NSOperationQueue(即串行队列)中,但是同样,各个方法在其他一些并发队列中运行。因此,执行顺序是相当随机的。现在,您可以像前面处理串行队列一样使用dispatch_group解决此问题。
-(void)testSerialQueue
{
self.group = dispatch_group_create();

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

NSBlockOperation *operation1 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation2 = [[NSBlockOperation alloc] init];
NSBlockOperation *operation3 = [[NSBlockOperation alloc] init];

[operation1 addExecutionBlock:^{
[self countTo100];
}];

[operation2 addExecutionBlock:^{
[self countFrom200To400];
}];

[operation3 addExecutionBlock:^{
[self countFrom400To500];
}];
}

- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}

- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);

});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

现在,您将看到计数再次有序。这是因为dispatch_group一直等待直到每个异步任务完成。

对于您的特定用例,您可以使用循环调用某些方法,像这样创建NSInvocationOperation,
-(void)testSerialQueue
{
self.group = dispatch_group_create();

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


NSArray *selectors = @[@"countTo100", @"countFrom200To400", @"countFrom400To500"];

for (NSString *selector in selectors) {
NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self
selector:NSSelectorFromString(selector)
object:nil];
[queue addOperation:operation];
}

}

- (void)countTo100
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 0; i < 100; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
}

- (void)countFrom200To400
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 200; i < 400; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);
});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

- (void)countFrom400To500
{
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_enter(self.group);

dispatch_async(concurrentQueue, ^{
for (int i = 400; i < 500; i++) {
NSLog(@"%d", i);
}
dispatch_group_leave(self.group);

});
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);

}

关于ios - NSOperationQueue在完成 block 成功时添加新操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30627344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com