Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/23.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
Objective c 在非常苛刻的应用程序上强制更新UI_Objective C_Multithreading_Macos_Cocoa_Nsprogressindicator - Fatal编程技术网

Objective c 在非常苛刻的应用程序上强制更新UI

Objective c 在非常苛刻的应用程序上强制更新UI,objective-c,multithreading,macos,cocoa,nsprogressindicator,Objective C,Multithreading,Macos,Cocoa,Nsprogressindicator,这是我的问题:我有一个应用程序,它必须进行数百万次计算(这是为了发表一篇科学论文) 为了加快计算速度,我学习了一些关于线程的知识,并做了以下工作: dispatch_queue_t myFirstQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group

这是我的问题:我有一个应用程序,它必须进行数百万次计算(这是为了发表一篇科学论文)

为了加快计算速度,我学习了一些关于线程的知识,并做了以下工作:

dispatch_queue_t myFirstQueue =
    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_group_t group = dispatch_group_create();

dispatch_group_async(group, myFirstQueue, ^{
    [Magic defineListOfSameDonInParticule:sharedData.particle];

    NSMutableDictionary *results = [Magic
            meanResultForSameDonInParticule:sharedData.particle];
});
Magic.m
中,我有一个名为
definelistofsamedoninparticle:
的方法,其中有:

[particule.donorsList enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                     usingBlock: ^(id keyA, Molecule *alpha, BOOL *stop){

    [particule.donorsList enumerateKeysAndObjectsWithOptions:NSEnumerationConcurrent
                   usingBlock: ^(id keyB, Molecule *beta, BOOL *stop2){

        if ([alpha isNotEqualTo:beta]) {
            float distance = [self distanceBetweenMolecule:alpha
                                               andMolecule:beta];

            [alpha.closestSame setObject:[NSNumber numberWithFloat:distance]
                                  forKey:beta.molID];

            [appDelegate increaseProgressionMeterByOne];
        }

    }];
在这段代码中,我有一个
[appDelegate IncrementProgressionMeterByone]
,它向我的应用程序代理发送一条消息,而我的应用程序代理又向我的进度条发送incrementBy:1

但是我所有的线程都被同时发生的数以百万计的计算所使用,因此UI冻结,我的progressBar无法前进

需要注意的是:我的进度条在不使用多线程的程序的其他部分工作正常

有没有办法强制更新UI?或者你对如何解决这个问题有什么想法

我知道更新UI会减慢应用程序的速度,但这对于应用程序的目标用户来说是必要的

非常感谢

更新:

下面是更新AppDelegate中UI的代码

- (void)increaseProgressionMeterByOne {
    [progressBar incrementBy:1];
}

您需要在
dispatch\u async(dispatch\u get\u main\u queue(),^{})中包装UI更新

Andrew的回答显示了如何包装对方法的调用,以便在主线程上执行它

dispatch_async(dispatch_get_main_queue(), ^
{
   [appDelegate increaseProgressionMeterByOne];
});
或者,如果您希望能够轻松地从不同线程安全地调用此方法,可以通过执行以下操作直接在方法本身中执行GCD调用:

- (void)increaseProgressionMeterByOne 
{
    if([NSThread isMainThread])
    {
        [progressBar incrementBy:1];
    }
    else
    {
        dispatch_async(dispatch_get_main_queue(), ^
            {
                [progressBar incrementBy:1];
            });
    } 
}

如果您的方法看起来像这样,您可以从任何线程安全地调用它,它将自动留在主线程上,或者使用GCD进入主线程。

您能显示更新UI的代码吗?你确定要在主线程上执行吗?你的代理回调发生在后台,所以我怀疑你可能不是。是的,问题正是我所想的。你只需要在主线程上执行UI更新。虽然同样的注意事项可能适用,但这个问题是关于Cocoa和AppKit的,而不是UIKit。我理解这意味着我必须始终在主线程上更新UI,但有没有办法确保UI在主线程上获得DIB?@TheTom你这是什么意思?我做到了,但是,每当我计算大的数字时,我的UI仍然冻结。甚至我点击的按钮也会一直保持在“开”的位置,直到所有计算结束