0

я хочу сделать следующее:NSNotification и управление потоком

1. display loader 
2. download database update and reload data 
3. hide loader 

Моей идеи для отправки уведомлений в начале и в конце методы обновления базы данных к основному контроллеру представления, так что вид контроллер отображает и скрывает загрузчик.

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

+0

Я бы не использовал уведомления. Блоки и диспетчер lib обеспечивают гораздо более четкий подход. См. Мой ответ. – CouchDeveloper

ответ

2

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

Если вы хотите быть на 100% уверенным, просто установите флаг где-нибудь и когда вы получите уведомление, проверьте, что базы данных перезагружены.

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

+0

Я не думаю, что флаг помог бы; вам нужна * гарантия *, что выполнение уведомлений будет * serialized *. Вы можете использовать атомарные операции, просто «предположите», что объект публикации использует определенный поток, или вы можете зарегистрировать наблюдателя с помощью 'addObserverForName: object: queue: usingBlock:', который требует NSOperationQueue. Все это громоздко или хрупко. ;) – CouchDeveloper

0

Обычно вы хотите ViewController чтобы зарезки обновление, так до тех пор, как вы убедитесь, что вы установили слушателя перед тем, что (стартового обновления), и после ваш ViewController полностью загружен, вы должны быть хорошо. (Т.е. начать обновление в viewDidAppear)

0

Вы могли бы реализовать его, как следующее:

- (IBAction)updateDatabase:(id)sender { 
    __block MyController* blockSelf = self; 
    __weak MyController* weakSelf = self; 
    [self startBusyIndicator]; 
    [self asyncDownloadDatabase:^(id result, NSError*error) { 
     if (error == nil) { 
      [blockSelf.database updateWithData:result]; 
     } 
     blockSelf = nil; 
     MyController* strongSelf = weakSelf; 
     if (strongSelf) { 
      dispatch_async(dispatch_get_main_queue(), ^{ 
       [strongSelf reloadData]; 
       [strongSelf stopBusyIndicator]; 
      }); 
     } 
    }]; 
} 

Использование blockSelf гарантирует, что контроллер не оставлял в живых до тех пор, после того, как asyncDownloadDatabase закончена, и база данных обновляется. Предполагается, что процесс обновления может быть выполнен в любом потоке.

weakSelf будет только нулевым и немедленно до тех пор, пока blockSelf не будет установлен на nil, если это последняя ссылка на контроллер - например, пользователь переключился на другое представление. В этом случае никакие представления не будут обновлены - они уже освобождены. В противном случае, если контроллер все еще существует, представления будут обновляться.