如何在GCD中停止DispatchWorkItem?

我目前正在玩

,发现了一个名为的课程DispatchWorkItem。该文档似乎有些不完整,所以我不确定是否正确使用它。我创建了以下代码段,并期望有所不同。我预计该项目将在调用后被取消cancel。但是由于某种原因,迭代仍在继续。有什么想法我做错了吗?该代码对我来说似乎很好。

@IBAction func testDispatchItems() {

let queue = DispatchQueue.global(attributes:.qosUserInitiated)

let item = DispatchWorkItem { [weak self] in

for i in 0...10000000 {

print(i)

self?.heavyWork()

}

}

queue.async(execute: item)

queue.after(walltime: .now() + 2) {

item.cancel()

}

}

回答:

GCD不会执行抢先取消。因此,要停止已经开始的工作项,您必须自己测试取消。在斯威夫特cancelDispatchWorkItem。在Objective-

C中,调用dispatch_block_cancel用创建的块dispatch_block_create。然后,您可以测试isCancelled在Swift中是否被取消(dispatch_block_testcancel在Objective-

C中称为)。

func testDispatchItems() {

let queue = DispatchQueue.global()

var item: DispatchWorkItem?

// create work item

item = DispatchWorkItem { [weak self] in

for i in 0 ... 10_000_000 {

if item?.isCancelled ?? true { break }

print(i)

self?.heavyWork()

}

item = nil // resolve span reference cycle of the `DispatchWorkItem`

}

// start it

queue.async(execute: item!)

// after five seconds, stop it if it hasn't already

queue.asyncAfter(deadline: .now() + 5) {

item?.cancel()

item = nil

}

}

或者,在Objective-C中:

- (void)testDispatchItem {

dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

static dispatch_block_t block = nil; // either static or property

__weak typeof(self) weakSelf = self;

block = dispatch_block_create(0, ^{

for (long i = 0; i < 10000000; i++) {

if (dispatch_block_testcancel(block)) { break; }

NSLog(@"%ld", i);

[weakSelf heavyWork];

}

block = nil;

});

// start it

dispatch_async(queue, block);

// after five seconds, stop it if it hasn't already

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

if (block) { dispatch_block_cancel(block); }

});

}

以上是 如何在GCD中停止DispatchWorkItem? 的全部内容, 来源链接: utcz.com/qa/423306.html

回到顶部