简体   繁体   English

在要求很高的应用上强制更新UI

[英]Force update UI on very demanding app

Here is my problem : I have an app that has to do literally millions of calculs (This is for a scientific paper to be published). 这是我的问题:我有一个应用程序必须执行数百万次计算(这是要发表的科学论文)。

So in order to speed up calculs I learned a little about threads and did this : 因此,为了加快计算速度,我对线程有了一些了解,并这样做:

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];
});

And in Magic.m I have a method named defineListOfSameDonInparticule: in which there is this: Magic.m我有一个名为defineListOfSameDonInparticule:的方法:

[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];
        }

    }];

in this piece of code I have [appDelegate increaseProgressionMeterByOne] which sends a message to my app delegate which in turn sends incrementBy:1 to my progress bar 在这段代码中,我有[appDelegate increaseProgressionMeterByOne] ,它向我的应用程序委托发送一条消息,该消息又向我的进度栏发送了gainBy:1

BUT all my threads are used by the millions of calculs happening at the same moment and so the UI freezes and my progressBar doesn't go forward. 但是我的所有线程都被同时发生的数百万次计算所使用,因此UI冻结了,我的progressBar不会前进。

To be noted : my progress bar works fine in other parts of the program which doesn't use multi-threading 需要注意的是:我的进度条在不使用多线程的程序的其他部分工作正常

Is there a way to force update the UI ? 有没有办法强制更新用户界面? Or do you have any idea on how to solve this ? 或者您对如何解决这个问题有任何想法?

I know updating the UI will slow down the app but it's necessary to the people the app is intended to ! 我知道更新用户界面会降低应用程序的运行速度,但对于应用程序预期的用户来说,这是必要的!

Thanks a lot ! 非常感谢 !

UPDATE : 更新:

Here is the code updating the UI in the AppDelegate 这是更新AppDelegate中的UI的代码

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

You will need to wrap UI updates within a dispatch_async(dispatch_get_main_queue(), ^{}); 您需要将UI更新包装在dispatch_async(dispatch_get_main_queue(), ^{}); . UIKit is not thread safe . UIKit不是线程安全的

Andrew's answer shows how to wrap the call to the method to perform it on the main thread. 安德鲁的答案显示了如何包装对方法的调用以在主线程上执行它。

dispatch_async(dispatch_get_main_queue(), ^
{
   [appDelegate increaseProgressionMeterByOne];
});

Alternatively, if you want to easily be able to call this method from different threads safely, you could perform the GCD call directly in the method itself by doing something like this: 另外,如果您想轻松地从不同线程安全地调用此方法,则可以通过执行以下操作直接在方法本身中执行GCD调用:

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

If your method were to look something like that, you could safely call it from any thread and it would automatically either stay on the main thread, or use GCD to get on it. 如果您的方法看起来像这样,则可以从任何线程安全地调用它,它会自动停留在主线程上,或使用GCD进入它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM