0

Вот моя проблема: у меня есть приложение, которое должно делать буквально миллионы вычислений (это для публикации научной статьи).Force update UI на очень требовательном приложении

Так что для того, чтобы ускорить calculs я узнал немного о потоках и сделал это:

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 У меня есть метод, называемый 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]; 
     } 

    }]; 

в этом фрагменте кода у меня есть [appDelegate increaseProgressionMeterByOne], который отправляет сообщение моему делегату приложения, который в свою очередь отправляет incrementBy: 1 в мой индикатор выполнения

НО все мои потоки используются миллионами вычислений, происходящих в тот же момент, и поэтому пользовательский интерфейс замерзает, и мой прогрессBar не продвигается вперед.

Чтобы отметить: мой прогресс бар прекрасно работает и в других частях программы, которая не использует многопоточность

Есть ли способ заставить обновить пользовательский интерфейс? Или у вас есть идея о том, как это решить?

Я знаю, что обновление пользовательского интерфейса замедлит приложение, но оно необходимо людям, к которым предназначено приложение!

Большое спасибо!

UPDATE:

Вот код обновления пользовательского интерфейса в AppDelegate

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

Можете ли вы показать код, который обновляет интерфейс? Вы уверены, что делаете это на основной теме? Ваш обратный вызов делегата происходит в фоновом режиме, поэтому я подозреваю, что вы не можете быть. – Dima

+0

Готово, любая идея? –

+0

Да, проблема в том, что я думал. Вам просто нужно выполнить обновление пользовательского интерфейса в основном потоке. – Dima

ответ

1

Ответ Эндрю показывает, как обернуть вызов методу для его выполнения в основном потоке.

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

В качестве альтернативы, если вы хотите, чтобы иметь возможность легко вызывать этот метод из различных потоков безопасно, можно выполнить вызов НОД непосредственно в самом методе, делая что-то вроде этого:

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

Если ваш метод должен был выглядеть примерно так, вы можете смело называть его из любого потока, и он автоматически либо останется на главной теме, либо использует GCD, чтобы попасть на него.

+0

Я сделал это, но мой пользовательский интерфейс все еще зависает, когда я вычисляю большие числа. Даже моя кнопка, на которую я нажимаю, остается на своем «включенном» положении до конца всех вычислений –

1

Вам нужно будет обернуть обновления пользовательского интерфейса в dispatch_async(dispatch_get_main_queue(), ^{});. UIKit is not thread safe.

+0

Хотя те же самые предостережения могут применяться, этот вопрос касается Cocoa и AppKit, а не UIKit. – NSGod

+0

Я понимаю, это означает, что мне всегда нужно обновлять пользовательский интерфейс в основном потоке, но есть ли способ убедиться, что пользовательский интерфейс получает dibs в основном потоке? –

+0

@ TheTom Что вы подразумеваете под этим? – Dima

Смежные вопросы