Насколько важно использовать `executeSelectorOnMainThread: withObject: waitUntilDone:` Из NSOperation? - PullRequest
4 голосов
/ 20 января 2011

Приложение для iPad синхронизируется с фидом XML и выполняет синхронизацию в подклассе NSOperation, выполняемом из NSOperationQueue. Когда он анализирует фид, он перезванивает в главный поток через performSelectorOnMainThread:withObject:waitUntilDone:, чтобы обновить различные части пользовательского интерфейса, запланировать загрузку и т. Д. Некоторые из них довольно дороги; пользовательский интерфейс иногда может перестать отвечать на запросы в течение одной или двух секунд во время синхронизации.

Чтобы сделать пользовательский интерфейс более отзывчивым, я исключил использование performSelectorOnMainThread:withObject:waitUntilDone: в пользу прямых вызовов для выполнения всех задач, связанных с синхронизацией, включая обновление пользовательского интерфейса. Так что теперь синхронизация происходит полностью в фоновом потоке, созданном NSOperationQueue. Кажется, это работает довольно хорошо, и пользовательский интерфейс намного быстрее реагирует на синхронизацию.

Однако я опасаюсь выпустить его таким образом. Я встречал некоторые упоминания в разных местах, что нужно обновлять интерфейс только в главном потоке (пример со ссылкой на AppKit ). Но я не смог найти ничего конкретного по этой теме в документации.

Итак, насколько важно обновить пользовательский интерфейс в главном потоке? Какие части приложения являются потокобезопасными, а какие нет? Возможно, есть ссылка, объясняющая, что безопасно выполнять в NSOperation и что должно выполняться только в основном потоке в iOS? Я действительно делаю что-то небезопасное или склонное к сбоям?

Ответы [ 4 ]

8 голосов
/ 20 января 2011

Чрезвычайно важно, чтобы вы всегда обновляли пользовательский интерфейс в главном потоке.Прикосновение к пользовательскому интерфейсу из фонового потока может вызвать всевозможные проблемы, включая повреждение внутреннего состояния, сбои или просто некорректное поведение.Любая работа, которая не требует касания пользовательского интерфейса, должна выполняться в фоновом потоке, но биты кода, которые обновляют пользовательский интерфейс, обязательно должны выполняться в основном потоке.

4 голосов
/ 23 января 2011

Сводка по безопасности потоков в Руководстве по программированию потоков обсуждает, какие базовые классы являются поточно-безопасными, а какие - нет.Полное резюме стоит краткого обзора быстрых ответов на общие вопросы.

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

Но в результате этого, согласно этому документу, важно выполнять обновления пользовательского интерфейса в главном потоке.

1 голос
/ 20 января 2011

Вы уверены, что вам нужна NSOperation?NSXMLParser.parse и NSURLConnection.start уже асинхронны.Если анализируемый вами класс обновляет некоторый объект модели, и ваш контроллер представления наблюдает за этим объектом модели с помощью KVO, вы можете получить более простой и эффективный код.

0 голосов
/ 24 сентября 2011

Дальнейшая документация и обсуждение содержатся в технической заметке, которая идет с образцом кода ListAdder. Это TN2109: «простая и надежная нарезка резьбы с помощью NSOperation». Он неоднократно говорит об обновлении только элементов UIKit из основного потока и приводит примеры правильных и неправильных реализаций. Вы можете найти дополнительные ссылки на него, выполнив поиск по теме «ограничение потока».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...