我觉得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:中的工作代码以Robert Ryan suggested here的方式调用主队列(主线程)上的一些UI修改代码。
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的问题,并知道解决方案?
我数小时后发现的:
发布于 2012-04-01 20:20:48
您所描述的问题不是来自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触摸第2代(一个可以说是非常老的设备)上运行了这段代码。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在这种情况下,队列切换比时间增加了不到千分之一秒。我建议您添加一些类似的日志,以查找您的延迟。
发布于 2012-04-01 16:35:55
顺便说一句,您每次调用dispatch_queue_create时都执行performHeavyCalculationAndUpdateUI吗?你做了很多次这个沉重的计算吗?如果是这样的话,您可能希望确保只创建一次队列,并根据需要分配给它。(通过将队列创建/发布与调度分离,还可以帮助您诊断导致性能问题的原因.GDC开销或performHeavyCalculationAndUpdateUI中的一些问题。最后,当您完成队列时,是否也执行dispatch_release?
有一些GCD开销,但我认为明智地使用创建和释放队列将是谨慎的,也将有助于诊断问题。
https://stackoverflow.com/questions/9965852
复制相似问题