dispatch_async已经滞后了,找不到哪里。有没有NSLog问题?

时间:2011-08-08 18:14:15

标签: iphone objective-c grand-central-dispatch

所以我有这段代码:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

//Bunch of code

NSLog(@"Test");

});

运行并立即返回nslog。但是代码的结果只会在屏幕上出现几秒延迟。在这里使用nslog是否存在问题,这意味着它通常会被调用,这使得它看起来很快,而实际上并非如此。我很困惑这个延迟来自哪里,因为NSLog正好在所有运行的代码的末尾。

另外,我的问题的另一个解决方案是,可以在调用每个方法时获得一个NSLog(有点像我想的NSZombiesEnabled)所以我可以确保没有一点我没注意到占用我的应用程序的甜蜜响应时间?

3 个答案:

答案 0 :(得分:11)

最近我自己也有类似的问题。您的延迟更新很可能是您在用户界面上执行的操作。这就是问题:你没有在应用程序的主线程中运行(也称为UI线程)。因此,无论您对用户界面所做的任何更改,实际上都不可见,直到......感觉就像显示一样,这往往会在应用程序中的其他内容触发重绘时发生。

你需要做的就是在你的块队列中你的UI线程中的图形更新如下:

dispatch_async(dispatch_get_main_queue(), ^{
        // Do GUI stuff.
    });

有时你的块可能很大或只是使用以前在主线程上运行的代码,因此很难将所有代码移动到特定的位置以在主队列上运行它。对于这些情况,请在块结尾的UI线程中对强制刷新进行排队:

dispatch_async(dispatch_get_main_queue(), ^{
        [self.somewidget setNeedsDisplay];
        [self.view setNeedsDisplay];
        [self.dontforgetme setNeedsDisplay];
    });

关于您的“应用程序占用我的应用程序的甜蜜响应时间”,您似乎正在尝试使用GDC来避免阻止用户界面。为了以编程方式确保您不会在UI线程中执行CPU密集型操作,反之亦然,您在UI块中运行GUI更新,我自己制作了以下宏:

/// Stick this in code you want to assert if run on the main UI thread.
#define DONT_BLOCK_UI() \
    NSAssert(![NSThread isMainThread], @"Don't block the UI thread please!")

/// Stick this in code you want to assert if run on a background thread.
#define BLOCK_UI() \
    NSAssert([NSThread isMainThread], @"You aren't running in the UI thread!")

正如您在评论中看到的那样,我倾向于在方法的开头使用这些宏,以确保我没有在错误的地方使用错误。我已将这些宏和更随机的内容放在https://github.com/gradha/ELHASO-iOS-snippets,您可能会发现它们很有用。

答案 1 :(得分:11)

UIKit不是线程安全的。你做的任何影响你的UI的调用需要在主线程上进行,否则你会得到奇怪的,不可预测的行为。例如:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // Background code that doesn't need to update the UI here

    dispatch_async(dispatch_get_main_queue(), ^{
        // UI code here
    });
});

答案 2 :(得分:-1)

使用//束代码,您应该粘贴真实代码,否则很难找到您的问题并浪费我们的时间。我想你可能在“一串代码”中更新了ui,它应该在主线程中。