比较 GCD 与 performSelectorInBackground:dispatch_async 不在后台 [英] comparison GCD vs. performSelectorInBackground: dispatch_async not in background

查看:25
本文介绍了比较 GCD 与 performSelectorInBackground:dispatch_async 不在后台的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Grand Central Dispatch 很棒,可以减少代码量,但为什么我不能在后台线程上运行一些东西?
我制作了一个示例应用程序来说明我的意思(没有评论的工作):

Grand Central Dispatch is great and reduces the amount of code but why I cannot run something on a background thread?
I have made a sample application to show what I mean (none of the commented work):

- (IBAction)performSel {
    [self performSelectorInBackground:@selector(doStuff) withObject:nil];
    [NSThread sleepForTimeInterval:3];
    [[self.view.subviews lastObject] removeFromSuperview];
}

- (IBAction)gcd {
    dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
    //dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
    //dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
    //dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
    //dispatch_async(dispatch_get_main_queue(), ^(void) {
    //dispatch_sync(dispatch_get_main_queue(), ^(void) {
        [self doStuff]; // only for readability, will move the code on success
    });
    [NSThread sleepForTimeInterval:3];
    [[self.view.subviews lastObject] removeFromSuperview];
}

- (void)doStuff {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

    UIView *abortingView = [[UIView alloc]initWithFrame: self.view.bounds];
    abortingView.backgroundColor = [UIColor whiteColor];
    abortingView.alpha = 0.7;
    [self.view insertSubview:abortingView atIndex:10];
    [abortingView release];

    [pool drain];
}

[NSThread sleepForTimeInterval:3];是模拟一个默认的UI功能.例如,如果有人从一个导航视图切换到另一个导航视图.
只需将代码复制到基于视图的新应用程序中,创建两个按钮并将它们连接起来.

the [NSThread sleepForTimeInterval:3]; is to simulate a default UI functionality. For example if someone is switching from one navigation view to another.
Simply copy the code in a new view based application, create two buttons and connect them.

推荐答案

UIKit 类只能在应用程序的主线程中使用.(从 iOS4 开始,绘制到图形上下文是线程安全的.)你不能在后台线程中使用 UIKit 的东西.

UIKit classes should be used only from an application’s main thread. (From iOS4, drawing to a graphics context is thread-safe.) You can't use UIKit stuff in a background thread.

因此,你只能在这种情况下使用 dispatch_async(dispatch_get_main_queue(), block).

Thus, you can only use dispatch_async(dispatch_get_main_queue(), block) in this situation.

dispatch_async(dispatch_get_main_queue(), ^(void) {

它将在主线程的runloop中调用主线程上的块.

It will invoke the block on the main thread in the runloop of the main thread.

dispatch_async(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

它将在后台线程中调用块.你不能使用它,因为你想在块中使用 UIKit.并且要小心dispatch_async(dispatch_queue_create(,这可能会导致内存泄漏,你必须释放dispatch_queue_create创建的串行队列.

It will invoke the block in a background thread. You can't use it because you want to use UIKit in the block. And be careful dispatch_async(dispatch_queue_create(, it might cause memory leak, you have to release the serial queue that is created by dispatch_queue_create.

dispatch_sync(dispatch_queue_create("myGCDqueue", NULL), ^(void) {
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {

dispatch_sync 一直等到块完成.

dispatch_sync waits until the block is done.

dispatch_sync(dispatch_get_main_queue(), ^(void) {

它会导致死锁.

这篇关于比较 GCD 与 performSelectorInBackground:dispatch_async 不在后台的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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