NSDefaultRunLoopMode против NSRunLoopCommonModes
Уважаемые хорошие люди из stackru,
Как и в прошлый раз, я поднимаю вопрос, на который недавно наткнулся. Я надеюсь, что кто-то может пролить свет на меня.
Всякий раз, когда я пытаюсь загрузить большой файл позади UIScrollView
, MPMapView
или что-то, процесс загрузки останавливается, как только я касаюсь экрана iPhone. К счастью, потрясающее сообщение в блоге Йорна предлагает альтернативный вариант, используя NSRunLoopCommonModes
для связи.
Это заставляет меня взглянуть на детали двух режимов, NSDefaultRunLoopMode и NSRunLoopCommonModes, но яблочный документ не любезно объясняет, кроме как сказать
NSDefaultRunLoopMode
Режим для работы с входными источниками, отличными от объектов NSConnection. Это наиболее часто используемый режим цикла выполнения.
NSRunLoopCommonModes
Объекты, добавленные в цикл выполнения с использованием этого значения в качестве режима, отслеживаются всеми режимами цикла выполнения, которые были объявлены как члены набора "общих" режимов, подробности см. В описании CFRunLoopAddCommonMode.
CFRunLoopAddCommonMode
Источники, таймеры и наблюдатели регистрируются в одном или нескольких режимах цикла выполнения и работают только тогда, когда цикл выполнения работает в одном из этих режимов. Общие режимы - это набор режимов цикла выполнения, для которых вы можете определить набор источников, таймеров и наблюдателей, которые совместно используются этими режимами. Вместо регистрации источника, например, в каждом конкретном режиме цикла выполнения, вы можете зарегистрировать его один раз в общем псевдо-режиме цикла выполнения, и он будет автоматически зарегистрирован в каждом режиме цикла выполнения в наборе общего режима. Аналогичным образом, когда режим добавляется в набор общих режимов, любые источники, таймеры или наблюдатели, уже зарегистрированные в общем псевдо-режиме, добавляются во вновь добавленный общий режим.
Кто-нибудь может объяснить, пожалуйста, два на человеческом языке?
1 ответ
Цикл выполнения - это механизм, который позволяет системе пробуждать спящие потоки, чтобы они могли управлять асинхронными событиями. Обычно, когда вы запускаете поток (за исключением основного потока), есть возможность запустить поток в цикле выполнения или нет. Если поток выполняет какую-либо сортировку или длительную операцию без взаимодействия с внешними событиями и без таймеров, вам не нужен цикл выполнения, но если ваш поток должен реагировать на входящие события, он должен быть присоединен к циклу выполнения, чтобы разбудить поток, когда приходят новые события. Это случай NSURLConnection
сгенерированные потоки, так как они просыпаются только при входящих событиях (из сети).
Каждый поток может быть связан с несколькими циклами выполнения или может быть связан с конкретным циклом выполнения, который можно настроить для работы в разных режимах. "Режим цикла выполнения" - это соглашение, используемое ОС для установления некоторых правил, когда следует доставлять определенные события или собирать их для последующей доставки.
Обычно все циклы выполнения устанавливаются в "режим по умолчанию", который устанавливает способ управления входными событиями по умолчанию. Например: как только происходит событие перетаскивания мышью (Mac OS) или касания (на iOS), режим для этого цикла выполнения устанавливается на отслеживание событий; это означает, что поток не будет разбужен новыми сетевыми событиями, но эти события будут доставлены позже, когда пользовательское событие ввода завершится и цикл выполнения снова установится в режим по умолчанию; очевидно, это выбор, сделанный архитекторами ОС, чтобы отдавать приоритет пользовательским событиям, а не фоновым событиям.
Если вы решили изменить режим цикла выполнения для вашего NSURLConnection
нить, используя scheduleInRunLoop:forModes:
, затем вы можете назначить поток специальному режиму цикла выполнения, а не конкретному циклу выполнения по умолчанию. Специальный псевдо-режим называется NSRunLoopCommonModes
используется многими источниками ввода, включая отслеживание событий. Например присвоение NSURLConnection
Экземпляр к общему режиму означает, что его события связываются с "режимом отслеживания" в дополнение к "режиму по умолчанию". Одно преимущество / недостаток связывания потоков с NSRunLoopCommonModes
является то, что поток не будет заблокирован сенсорными событиями.
Новые режимы могут быть добавлены к общим режимам, но это довольно низкоуровневая операция.
Я хотел бы завершить, добавив несколько заметок:
Как правило, нам нужно использовать набор изображений или миниатюр, загруженных из сети с представлением таблицы. Мы можем думать, что загрузка этих изображений из сети во время прокрутки табличного представления может улучшить взаимодействие с пользователем (поскольку мы могли видеть изображения во время прокрутки), но это не является преимуществом, поскольку плавность прокрутки может сильно пострадать. В этом примере с
NSURLConnection
цикл выполнения не должен использоваться; было бы лучше использоватьUIScrollView
делегировать методы для обнаружения прекращения прокрутки, а затем обновлять таблицу и загружать новые элементы из сети;Вы можете рассмотреть возможность использования GCD, который поможет вам "защитить" свой код от проблем управления циклами выполнения. В приведенном выше примере вы можете рассмотреть возможность добавления сетевых запросов в пользовательскую последовательную очередь.