Что означает isConcurrent для NSOperation, запущенной из NSOperationQueue?


Потому что NSOperationQueue всегда запускает задачи в новом потоке, Меня смущает роль isConcurrent, Когда NSOperation бежит от NSOperationQueue.

Если у меня есть два подкласса NSOperation, оба выполняющих асинхронные процессы, оба запускаются из NSOperationQueue и в обоих я переопределяю isCancelled, isExecuting, isFinished и isReady. Какая будет разница, если в одном я переопределяю isConcurrent Всегда return YES, а в другом всегда return NO.

Кто на самом деле звонит isConcurrent? Как меняется логика, если она NO или YES.

3 6

3 ответа:

Это устаревший метод, используемый до OS X v10. 6 и до iOS 4, то есть до введения GCD для NSOperationQueue диспетчеризации.

Из doc

Операционные очереди обычно предоставляют потоки, используемые для выполнения их операций. В OS X v10.6 и более поздних версиях очереди операций используют библиотеку libdispatch (также известную как Grand Central Dispatch) для инициализации выполнения своих операций. В результате операции всегда выполняются в отдельном потоке , независимо от обозначаются ли они как параллельные или не-параллельные операции. в OS X v10. 5, однако, операции выполняются на отдельных потоках только в том случае, если их метод isConcurrent возвращает NO. Если этот метод возвращает значение YES, ожидается, что объект operation создаст свой собственный поток (или запустит некоторую асинхронную операцию); очередь не предоставляет для него поток.

Если вы используете OS X >= 10.6 или iOS >= 4, Вы можете спокойно игнорировать его.

Как подтверждение этого факта, от Дока оф isConcurrent

В OS X v10.6 и более поздних версиях очереди операций игнорируют значение, возвращаемое этим методом, и всегда запускают операции в отдельном потоке.

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


Хорошо, я был вполне доволен своим использованием метода isConcurrent до сегодняшнего дня !

Я прочитал предложение:

В OS X v10.6 и более поздних версиях очереди операций игнорируют значение, возвращаемое этот метод и всегда запускает операции на отдельном потоке.

В качестве предупреждения, относящегося к QA1712, указывая, что для параллельных операций start метод теперь может быть вызван в другом потоке, чем тот, который поставил операцию в очередь, что является изменением в 10.6 и iOS 4.

Я не прочитал это как указание на то, что метод isConcurrent полностью игнорируется очередью и не имеет никакой цели вообще, просто он больше не влияет на поток, на котором start вызывается. Возможно, я неправильно понял это.

Я также неправильно понял первоначальный вопрос как более общий о параллельных операциях и флаге isConcurrent, а также принятый ответьте так же эффективно, сказав

Флаг isConcurrent можно игнорировать начиная с версии 10.6 и iOS 4

Я не уверен, что это правильно.

Если я понимаю первоначальный вопрос сейчас, перефразируя:

Учитывая правильно построенный параллельный NSOperation флаг isConcurrent действительно ли изменяет выполнение операции вообще?

Я думаю, что трудно сказать для всех возможных установок, но мы можем сказать это:

  1. Она не устарела. Это нормально для Apple, чтобы осуждать методы это уже бесполезно.

  2. Документация последовательно ссылается на то, что метод является обязательным переопределение.

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

Я создал быстрый тестовый проект с NSOperation, который перекрывал isConcurrent и main только, isConcurrent не вызывался ни на одном этапе. Хотя это был очень простой тест. Я предполагаю, что вы, возможно, также проверили его? Я предположил, что, возможно, если NSOperationQueue не назовет его NSOperation's реализация по умолчанию start может.

Так, где это оставляет нас? Очевидно, что нет никаких проблем, чтобы реализовать его и вернуть YES, чтобы удовлетворить документированные требования. Однако с моей точки зрения, я думаю, что это слишком большой скачок, чтобы уйти от предостережения относительно 10.6 и iOS 4.0, чтобы сказать, что теперь его можно смело игнорировать.


Мой Первоначальный Ответ...

isConcurrent не является устаревшим методом и не игнорируется NSOperationQueue. Документация, приведенная в других ответах, немного неясна и легко может быть неправильно понята.

isConcurrent = YES означает, что операция предоставляет свои собственные средства параллелизма. Или, говоря по-другому, операция "isAlreadyConcurrent" и не нуждается в NSOperationQueue, чтобы обеспечить и управлять параллелизмом. Поскольку NSOperationQueue больше не обеспечивает параллелизм, вам нужно сообщить ему, когда операция isFinished или если она isCancelled (и т. д.), Следовательно, необходимо переопределить эти методы.

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

Тогда возникает очевидный вопрос: "Зачем помещать уже параллельную операцию в NSOperationQueue?- Это для того, чтобы операция могла извлекайте пользу из других особенностей NSOperationQueue , таких как зависимости и т. д. Вводящая в заблуждение часть документации относится только к тому потоку, на котором вызывается метод start NSOperation. Это изменение вызвало проблему, обсуждавшуюся в QA1712.

Перефразируя первоначальный вопрос следующим образом:

При правильно построенном параллельном NSOperation действительно ли значение, возвращаемое isConcurrent, изменяет выполнение операции вообще?

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

Назначение флага описывается только следующим образом:

Верните YES, если операция выполняется асинхронно по отношению к текущему потоку или нет, если операция выполняется синхронно с любым потоком, который ее запустил.

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


Дополнительные Примечания:

В документации содержится ссылка на изменение способа использования этого значения NSOperationQueue до и после OSX 10.6 и iOS 4.0.

В OS X v10.6 очереди операций игнорируют значение, возвращаемое isConcurrent, и всегда вызывают метод start вашей операции из отдельного потока. Однако в OS X v10.5 очереди операций создают поток только в том случае, если isConcurrent возвращает значение NO. ...

Это изменение вызвало проблему, описанную вQA1712 . Этот комментарий обычно интерпретируется как подразумевающий, что флаг isConcurrent больше не используется после 10.6 и iOS 4 и может быть проигнорирован. Я с этим не согласен интерпретация как метод не была официально признана устаревшей и до сих пор документируется как обязательное переопределение для параллельных операций. Кроме того, тот факт, что его использование изменилось в прошлом, является напоминанием о том, что он может измениться снова в будущем, поэтому мы должны правильно реагировать, даже если мы подозреваем, что в настоящее время он не имеет никакого эффекта.