我有以下调度队列我的应用程序:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^ {
[activeModel freeUpMallocedData];
// UI Updates have to be made on the main thread, so request from GCD.
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^ {
[mainViewController removeTidyUpScreen];
[mainViewController showSceneList];
[activeModel release];
});
});
freeUpMallocedData方法更新UI进度视图:
- (void) freeUpMallocedData {
// Calculate the percentage increase for each item in the pointerStorageArray as it is released so we can update the Progress Screen.
float arrayCount = [pointerStorageArray count];
float incrementCounter = 1 / arrayCount; // Caculates 1% of pointerStorageArray
float newValue = incrementCounter;
int stepCounter = 0;
NSString * message;
// Now iterate through the pointerStorageArray and free all malloced memory.
for (NSValue * value in pointerStorageArray) {
stepCounter ++;
newValue = newValue + incrementCounter;
message = [NSString stringWithFormat:@"Freeing Up Memory (%d of %d) ...", stepCounter, (int)arrayCount];
free(value);
[self tidyUpProgress:message amount:newValue];
}
}
然后在主线程上执行tidyUpProgress方法。
- (void) tidyUpProgress: (NSString *) progressMsg amount: (float) amount {
if (tidyUpMonitorDelegate) {
tidyUpProgressMsg = progressMsg;
tidyUpProgressAmount = amount;
[tidyUpMonitorDelegate performSelectorOnMainThread:@selector(model3DTidyUpProgressUpdate) withObject:nil waitUntilDone:NO];
}
}
- (void) model3DTidyUpProgressUpdate {
progressView.progress = app.activeModel.tidyUpProgressAmount;
loadingStatus.text = app.activeModel.tidyUpProgressMsg;
}
问题是当freeUpMallocedData方法完成时应用程序崩溃。原因是我的初始调度队列继续请求主队列,然后释放activeView。这似乎是在tidyUpMonitorDelegate执行其上次更新之前劫持线程 - 当它获得主线程时,activeView已经被释放,因此当app3DTidyUpProgresUpdate方法请求访问类中的变量时,应用程序崩溃了dealloced。
有人可以就如何解决这个时间问题提出建议吗?
提前谢谢。
答案 0 :(得分:3)
只是想一想 - 尝试在调度中重命名变量:
dispatch_queue_t mainqueue = dispatch_get_main_queue();
dispatch_async(mainqueue, ^ {
答案 1 :(得分:0)
使用两种不同的机制在主线程中调度任务:dispatch_asyc和performSelectorInMainThread:withObject:waitUntilDone:。每个机制都使用自己的队列,由主运行循环读取。
未定义读取这些队列的顺序。因此,performSelectorInMainThread:withObject:waitUntilDone调度的任务可以在使用dispatch_async调度的任务之后(或之前)执行,无论先调度哪个任务。
您应该更新tidyUpProgress:使用dispatch_async。然后订单将得到保证。
此外,在释放对象后,应始终使保存对该对象的引用的变量无效。
答案 2 :(得分:-3)
这是错误的方式:
float arrayCount = [pointerStorageArray count];
- 正确方式:
NSUinteger arrayCountInt = [pointerStorageArray count];
NSNumber *arrayCountNumber = [NSNumber numberWithUnsignedInteger:arrayCountInt]
float arrayCount = [arrayCountNumber floatValue];