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

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

问题描述

大中央调度是伟大的,减少了code的量,但为什么我不能运行在后台线程的东西吗?结果
我做了一个示例应用程序来说明我的意思(没有评论工作):

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功能。例如,如果某人从一个导航视图切换到另一个。结果
只需将code复制一个新的视图基于应用程序,创建两个按钮和连接它们。

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(),块)。

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天全站免登陆