gpt4 book ai didi

ios - Block_release 在后台线程上释放 UI 对象

转载 作者:IT王子 更新时间:2023-10-29 08:16:12 25 4
gpt4 key购买 nike

在 WWDC 2010“Blocks and Grand Central Dispatch”演讲中提出的模式之一是使用嵌套的 dispatch_async 调用在后台线程上执行耗时任务,然后在任务完成后更新主线程上的 UI

dispatch_async(backgroundQueue, ^{
// do something time consuming in background
NSArray *results = ComputeBigKnarlyThingThatWouldBlockForAWhile();

// use results on the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[myViewController UpdateUiWithResults:results];
});
});

由于“myViewController”在 block 内使用,它会自动获得“保留”,稍后会在清理 block 时获得“释放”。

如果 block 的“释放”调用是最终释放调用(例如,用户在后台任务运行时离开 View ),则调用 myViewController dealloc 方法——但它是在后台线程上调用的!!

UIKit 对象不喜欢在主线程之外被释放。在我的例子中,UIWebView 抛出异常。

这个 WWDC 提出的模式 - 特别提到作为避免 UI 锁定的最佳新方法 - 怎么会如此有缺陷?我错过了什么吗?

最佳答案

对于这种情况,您可以使用 __block 存储类型限定符。 __block 变量不会被 block 自动保留。所以需要自己保留对象:

__block UIViewController *viewController = [myViewController retain];
dispatch_async(backgroundQueue, ^{
// Do long-running work here.
dispatch_async(dispatch_get_main_queue(), ^{
[viewController updateUIWithResults:results];
[viewController release]; // Ensure it's released on main thread
}
});

编辑

使用 ARC,__block 变量对象自动被 block 保留,但我们可以将 nil 值设置为 __block 变量,以便在需要时释放保留的对象。

__block UIViewController *viewController = myViewController;
dispatch_async(backgroundQueue, ^{
// Do long-running work here.
dispatch_async(dispatch_get_main_queue(), ^{
[viewController updateUIWithResults:results];
viewController = nil; // Ensure it's released on main thread
}
});

关于ios - Block_release 在后台线程上释放 UI 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6353471/

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