Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
主线程冲突/计时问题-GCD-iPhone_Iphone_Objective C_Multithreading_Thread Safety_Grand Central Dispatch - Fatal编程技术网

主线程冲突/计时问题-GCD-iPhone

主线程冲突/计时问题-GCD-iPhone,iphone,objective-c,multithreading,thread-safety,grand-central-dispatch,Iphone,Objective C,Multithreading,Thread Safety,Grand Central Dispatch,我的应用程序中有以下调度队列: 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_

我的应用程序中有以下调度队列:

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已被释放,因此当model3DTidyUpProgresUpdate方法请求访问现已解除分配的类中的变量时,应用程序崩溃

有人能就如何解决这个时间问题提供建议吗

先谢谢你

这是错误的方式:

浮点数组计数=[PointerStorage数组计数]

-正确的方法:

NSUinteger  arrayCountInt = [pointerStorageArray count]; 
NSNumber *arrayCountNumber = [NSNumber numberWithUnsignedInteger:arrayCountInt]
float arrayCount = [arrayCountNumber floatValue];

您使用两种不同的机制来调度主线程中的任务:dispatch_asyc和performSelectorInMainThread:withObject:waitUntilDone:。每个机制都使用自己的队列,由主运行循环读取

读取这些队列的顺序未定义。因此,由performSelectorInMainThread:withObject:waitUntilDone调度的任务可以在使用dispatch_async调度的任务之后或之前执行,而不管先调度哪个任务

您应该更新tidyUpProgress:以使用dispatch\u async。那么订单就有保证了


此外,在释放一个对象后,您应该始终使保存该对象引用的变量为空。

只是一个想法-尝试在分派中重命名该变量:

dispatch_queue_t mainqueue = dispatch_get_main_queue();
dispatch_async(mainqueue, ^  {  

实际上,它是完全有效的,这里显示的所有额外步骤都是不必要的。另外,这个答案并没有解决这个问题。我过去在类型转换中有一些奇怪的错误,比如,这就是为什么我建议尝试这样做的原因—但似乎没有帮助—如果我将TidyApprogress更改为以下内容,我仍然会遇到同样的问题dispatch_queue_t queue=dispatch_get_main_queue dispatch_asyncqueue,^{[tidyUpMonitorDelegate Model3DTidyApprogressUpdate];}哪一个?tidyUpMonitorDelegate中的那个还是另一个?啊,它工作得很好!你真是个天才,很简单,谢谢你!在块中,它会在块中使用的变量的注释范围之外进行“复制”或保留,以防它们在块执行之前消失——因此我在本例中进行了计算,因为您的变量具有相同的名称,而块不知道您实际上要调用哪一个!