Ответ 1
NSOperation*
классы - это более высокий уровень api. Они скрывают от вас GCD нижнего уровня api, чтобы вы могли сосредоточиться на выполнении задачи.
Правило большого пальца: Сначала используйте api самого высокого уровня, а затем деградируйте на основе того, что вам нужно выполнить.
Преимущество такого подхода заключается в том, что ваш код остается наиболее агностическим для конкретной реализации, предоставляемой поставщиком.
В этом примере, используя NSOperation
, вы будете использовать реализацию очередей выполнения Apple (используя GCD). Если Apple когда-либо решит изменить детали реализации за кулисами, они могут сделать это, не нарушая код приложения.
Одним из таких примеров будет Apple, обесценивающий GCD и использующий совершенно другую библиотеку (что маловероятно, потому что Apple создала GCD, и все, похоже, любят ее).
Что касается вопроса, я рекомендую обратиться к следующим ресурсам:
- http://nshipster.com/nsoperation/
- https://cocoasamurai.blogspot.de/2009/09/guide-to-blocks-grand-central-dispatch.html
- https://cocoasamurai.blogspot.de/2009/09/making-nsoperation-look-like-gcd.html
- https://www.raywenderlich.com/76341/use-nsoperation-nsoperationqueue-swift
- https://developer.apple.com/documentation/foundation/operationqueue
- Видео: расширенные NSOperations, WWDC 2015, сеанс 226
- Пример кода: Advanced NSOperations, WWDC 2015
- Видео: создание ответных и эффективных приложений с GCD, WWDC 2015, сессия 718
Теперь, касаясь ваших конкретных вопросов:
В чем разница между отправкой _ *() и NSOperationQueue, [...]
См. выше.
[...] и есть ли какая-либо причина (техническая, производительность, стилистика или иное), что я должен использовать один над другим?
Если материал NSOperation
выполняет вашу работу, используйте его.
Является ли NSOperationQueue только оболочкой Objective-C вокруг dispatch_async, или есть ли что-то еще для этого?
Да, это в основном. Плюс такие функции, как операционные зависимости, простой запуск/остановка.
Изменение
Говорят, что использование самого высокого уровня api может показаться интригующим. Конечно, если вам нужен быстрый способ запускать код в определенном потоке, вы не хотите писать много шаблонов кода, что делает использование функций более низкого уровня C совершенно допустимым:
dispatch_async(dispatch_get_main_queue(), ^{
do_something();
});
Но рассмотрим это:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
do_something();
}];
Я бы порекомендовал последнее, потому что большинство из того, что вы напишете, Objective-C, так почему бы не принять его выразительность?