Block_release在后台线程上释放UI对象 [英] Block_release deallocating UI objects on a background thread

查看:604
本文介绍了Block_release在后台线程上释放UI对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆