iphone - 在什么情况下GCD会对旧设备产生负面性能影响?

标签 iphone ios ipad concurrency grand-central-dispatch

我在 GCD 中遇到了一些奇怪的事情。

首先,我有一个执行大量计算的方法,然后进行一些 UI 布局计算并根据结果更新 UI。

如果没有 GCD,每次调用此方法时,UI 都会卡住大约 0.5 秒

所以我去了 GCD 并做了这个:

// INIT
// stored in ivar (called only once!)
dispatch_queue_t q = dispatch_queue_create("com.testcompany.myqueue", NULL);


// WORK
dispatch_async(q, ^(void) {
    [self performHeavyCalculationAndUpdateUI]; // modifies self.calculationData
});

进行此更改后,该方法大约需要2-5 秒,直到更改出现在 UI 中。

在串行队列中运行的-performHeavyCalculationAndUpdateUI:中的工作代码会调用主队列(主线程)上的一些UI修改代码Robert Ryan suggested here :

dispatch_async(dispatch_get_main_queue(), ^{
    // Read ivars and objects used during calculation in the serial queue (problem?)
    CalculationData *result = self.calculationData;

    // UI updates like [foo addSubview:bar];
});

在主队列上,我还读取了一些在串行后台队列中计算期间使用的 ivars 和对象。这会是一个问题吗?

仍然需要大约 2-5 秒才能出现某些内容。比没有 GCD 的时间长得多。

除了这里,我没有在其他任何地方使用 GCD。

有其他人在 GCD 中遇到过此类问题并知道解决方案吗?

几个小时后我发现:The Reason .

最佳答案

您所描述的问题不是来自 GCD,至少不是来自您发布的代码。我做了一个快速测试功能来记录切换队列所需的时间:

-(IBAction)beginWork:(id)sender{
    NSTimeInterval buttonPushTime = [NSDate timeIntervalSinceReferenceDate];
    // Defined as an ivar : dispatch_queue_t q;
    // created as "q = dispatch_queue_create("com.testcompany.myqueue", NULL);" in viewDidLoad
    dispatch_async(q, ^{
        NSTimeInterval backgroundBeginTime = [NSDate timeIntervalSinceReferenceDate];
        [NSThread sleepForTimeInterval:5.0];
        NSTimeInterval backgroundEndTime = [NSDate timeIntervalSinceReferenceDate];
        dispatch_async(dispatch_get_main_queue(), ^{
            NSTimeInterval backOnMainThreadTime = [NSDate timeIntervalSinceReferenceDate];

            NSLog(@"seconds to start on background thread = %f",backgroundBeginTime-buttonPushTime);
            NSLog(@"seconds to perform in background      = %f",backgroundEndTime-backgroundBeginTime);
            NSLog(@"seconds to get main thread again      = %f",backOnMainThreadTime-backgroundEndTime);
            NSLog(@"total seconds                         = %f",backOnMainThreadTime-buttonPushTime);
        });
    });
}

然后我在我的 iPod touch 2nd gen(可以说是非常旧的设备。iOS 4.2.1)上运行了这段代码。结果如下:

seconds to start on background thread = 0.001747
seconds to perform in background      = 5.000142
seconds to get main thread again      = 0.000190
total seconds                         = 5.002079

本例中的队列切换增加的时间不到千分之二秒。我建议您添加一些类似的日志记录来查找延迟。

关于iphone - 在什么情况下GCD会对旧设备产生负面性能影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9965852/

相关文章:

ios - Swift Sprite 套件 : How do you set an animation for a random time?

iphone - iOS 从网页下载数据的问题,NSURL

iOS:分发版本是否应该在我的开发者设备上运行?

iphone - 分析器报告以下代码泄漏

ios - 选择器与 Action Swift 4

ios - 如何使用开源框架或免费工具创建 Newsstand Magazine App?

iphone - 即使消息发送失败,也会发送 MessageComposeResult

ios - UICollectionView 的分页以在屏幕上显示一个完整单元格和两个部分单元格

iphone - 在 Objective C 中使用 #define 或 extern NSString *const 哪个更好

ipad - 在 iPad 上访问本地主机