NSThread и обновление объектов в подпредставлениях - PullRequest
2 голосов
/ 18 апреля 2011

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

Этот процесс можно запустить из разных представлений, поэтому я поместил код обновления в мой делегат приложения. При нажатии на метод обновления у меня есть этот код:

MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[NSThread detachNewThreadSelector:@selector(startTheBackgroundJob) toTarget:delegate withObject:nil];

В моем делегате:

- (void)startTheBackgroundJob {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
//do some stuff here
    self.percentageCompleted = (i * 100) / totalChars;
    [[NSNotificationCenter defaultCenter] postNotificationName:@"refreshObjectsForUpdate" object:self];
//some other stuff
    [pool release];

По сути, в моей теме я хочу обновить различные Прогресс-прогресс с текущим прогрессом. Поэтому я использовал NSNotificationCenter для отправки сообщения после каждого шага в моей теме.

В viewController я ловлю это сообщение и делаю:

MyAppDelegate *delegate = [[UIApplication sharedApplication] delegate];

double prc = delegate.percentageCompleted;
UILabel *l = (UILabel *)[self.view viewWithTag:444];
l.text = [NSString stringWithFormat:@"%f", prc];

Но он обновляет мой ярлык только в конце потока.

В чем здесь проблема? Могу ли я использовать другой подход для этого?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 18 апреля 2011

С Документация Apple :

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

, поэтому вам необходимо выполнить свой код для явного обновления пользовательского интерфейса в основном потоке (с performSelectorOnMainThread:withObject:waitUntilDone: или любым другим подходящим).

2 голосов
/ 18 апреля 2011

@ paulbailey правильно о выполнении селектора в главном потоке.Я также хотел бы добавить, что если вы работаете с высокой производительностью, я бы вообще не использовал центр уведомлений.Он будет транслироваться синхронно, что означает, что каждый элемент пользовательского интерфейса будет обновляться при каждой итерации цикла.Вы можете использовать флаг «waitUntilDone» в методе executeSelector, чтобы сделать его асинхронным, но вы можете вызвать много потоков и переключений контекста.

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

...