我在 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/