Block_release在后台线程上释放UI对象 [英] Block_release deallocating UI objects on a background thread
问题描述
WWDC 2010Blocks and Grand Central Dispatch演讲中提出的模式之一是使用嵌套的dispatch_async调用在后台线程上执行耗时的任务,然后在任务完成后更新主线程上的UI
One of the patterns presented at the WWDC 2010 "Blocks and Grand Central Dispatch" talk was to use nested dispatch_async calls to perform time consuming tasks on a background thread and then update the UI on the main thread once the task is complete
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正在块中使用,它会自动获得保留并稍后清理块时获得释放。
Since "myViewController" is being used inside the blocks, it automatically gets a 'retain' and will later get a 'release' when the blocks are cleaned up.
如果块的'release'调用是最终的释放调用(例如,用户在后台任务运行时导航远离视图)myViewController dealloc方法是调用 - 但它在后台线程上调用!!
If the block's 'release' call is the final release call (for example, the user navigates away from the view while the background task is running) the myViewController dealloc method is called -- but it's called on the background thread!!
UIKit对象不喜欢在主线程之外取消分配。在我的例子中,UIWebView引发了异常。
UIKit objects do not like to be de-allocated outside of the main thread. In my case, UIWebView throws an exception.
这个WWDC如何呈现模式 - 特别提到避免UI锁定的最佳新方法 - 是如此有缺陷?我错过了什么吗?
How can this WWDC presented pattern - specifically mentioned as the best new way to avoid UI lockup - be so flawed? Am I missing something?
推荐答案
您可以使用 __ block
存储类型限定符来处理这种情况。 __ block
块不会自动保留变量。所以你需要自己保留对象:
You can use the __block
storage type qualifier for such a case. __block
variables are not automatically retained by the block. So you need to retain the object by yourself:
__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变量对象会被块自动保留,但我们可以将nil值设置为__block变量。用于释放每当我们要被保持的物体
With ARC, __block variable object is automatically retained by the block, but we can set nil value to the __block variable for releasing the retained object whenever we want.
__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
}
});
这篇关于Block_release在后台线程上释放UI对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!