2013-08-27 2 views
14

Я пытаюсь понять, почему операции пользовательского интерфейса не могут быть выполнены с использованием нескольких потоков. Это также требование в других рамках, таких как OpenGL или cocos2d?Почему должны выполняться операции UIKit в основном потоке?

Как насчет других языков, таких как C# и javascript? Я пробовал искать в google, но люди упоминают о потоках POSIX, которые я не понимаю.

ответ

13

In Cocoa Touch, UIApplication т. Е. Экземпляр приложения прилагается к основному потоку, потому что этот поток создается UIApplicatioMain(), функцией точки входа Cocoa Touch. Он устанавливает основной цикл событий, включая цикл запуска приложения, и начинает обработку событий. Основной цикл событий приложения получает все события пользовательского интерфейса т.е. прикосновения, жесты и т.д.

От Docs UIApplicationMain(),

Эта функция инициализирует объект приложения из основного класса и инициализирует делегат (если таковые имеются) от данного класса и задает делегат для приложения. Он также устанавливает основной цикл событий, включая цикл запуска приложения, и начинает обработку событий. Если файл Info.plist приложения указывает основной загружаемый файл nib, включая ключ NSMainNibFile и действительное имя файла nib для значения, эта функция загружает этот файл nib.

Эти события пользовательского интерфейса приложения дополнительно направлены UIResponder «s после цепи респондеров обычно как UIApplication ->UIWindow ->UIViewController ->UIView -> подвиды (UIButton и др.)

ответчики обрабатывать события например, нажатие кнопки, кратковременное нажатие, увеличение зума, салфетки и т. д., которые переводится как изменение в пользовательском интерфейсе. Следовательно, поскольку вы можете видеть, что эта цепочка событий встречается в основном потоке, поэтому UIKit, структура, содержащая респондентов, должна работать в основном потоке.

С снова UIKit документов,

По большей части, классы UIKit должны использоваться только из основного потока приложения. Это особенно справедливо для классов, полученных из UIResponder, или для управления пользовательским интерфейсом вашего приложения.

EDIT

Почему DrawRect должен быть на главном потоке?

drawRect: вызывается UIKit как часть жизненного цикла UIView «ы. Итак, drawRect: привязан к основной теме. Рисование таким образом дорого, потому что это делается с использованием центрального процессора. Аппаратное ускорение графики обеспечивается с помощью технологии CALayer (Core Animation).

CALayer с другой стороны выступает в качестве резервного хранилища для представления. После этого представление просто отобразит кэшированное растровое изображение текущего состояния. Любое изменение свойств вида приведет к изменениям в хранилище резервных копий, которые будут выполняться графическим процессором на резервной копии. Тем не менее, представление по-прежнему должно обеспечивать исходный контент и периодически обновлять представление. Я не работал над OpenGL, но я думаю, что он также использует слои (я мог ошибаться).

Я попытался ответить на это, насколько мне известно. Надеюсь, это поможет!

+0

Я согласен с тем, что вы сказали. Предположим, что ответчик находится в основном потоке, и нам нужен основной поток для получения событий, но как насчет рендеринга UIView? Зачем нам нужен drawRect в основном потоке. Многие чертежи также могут быть выполнены и оптимизированы с помощью muti-threading, почему инфраструктура UIKit не позволяет это? Кроме того, я думаю, что UIKIt ускорен GPU, который использует многопоточность. Возможно, я ошибаюсь. –

+0

@KunalBalani Пожалуйста, проверьте мои изменения – Amar

+0

См. Http://stackoverflow.com/questions/21139300/having-uiview-drawrect-occur-in-a-background-thread –

-1

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

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

Я не знаю, что это такое в C# для приложений для Windows Phone, но я бы ожидал, что он будет таким же. В Android система даже не позволит вам делать что-то вроде загрузки в основном потоке, создавая фоновый поток напрямую.

Как правило, если вы думаете о главном потоке, подумайте «что видит пользователь».

1

C# ведет себя одинаково (см. Здесь: Keep the UI thread responsive). Обновления пользовательского интерфейса должны выполняться в потоке пользовательского интерфейса - большинство других вещей должно выполняться в фоновом режиме.

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

-1

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

В случае пользовательского интерфейса iOS и MacOS X было принято решение сделать поток пользовательского интерфейса безопасным, только позволив и выполнив методы пользовательского интерфейса в основном потоке. Вот и все.

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

1

от: https://www.objc.io/issues/2-concurrency/thread-safe-class-design/

Это сознательное решение, дизайн со стороны Apple, чтобы не иметь UIKit быть потокобезопасным. Обеспечение его потокобезопасностью не будет покупать вас с точки зрения производительности; это на самом деле делало бы что-то еще медленнее. И тот факт, что UIKit привязан к основному потоку, позволяет легко писать параллельные программы и использовать UIKit. Все, что вам нужно сделать, это убедиться, что вызовы в UIKit всегда выполняются в основном потоке.

Таким образом, в соответствии с этим факт, что объекты UIKit должны быть доступны в основном потоке, является дизайнерским решением Apple в пользу производительности.

+0

Я не согласен с этим. Это все платформы, включая symbian, android, blackberry, и большинство из них существует до iOS. Это тоже сервлеты Java и другие инструменты GUI. Они не ограничиваются мобильной платформой. –

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