Разница между NSThreads, NSOperations и executeSelector - PullRequest
6 голосов
/ 03 марта 2011

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

Еще одна вещь, в чем разница между этими двумя утверждениями, написанными ниже: -

[self getData];

[self performSelector:@selector(getData)];

Please explain as i dont know the difference between all these things. 

Ответы [ 3 ]

10 голосов
/ 03 марта 2011

Фактическая небольшая разница между

[self getData];

И

[self performSelector:@selector(getData)];

Единственная разница заключается в том, что когда вы вызываете [self getData], компилятор может определить, что вы хотите отправитьgetData сообщение для объекта класса [self class].И если он не может найти прототипы методов, которые были объявлены ранее, появится предупреждение.

Первая и вторая строки будут переведены в

objc_msgsend(self, _cmd)

performSelector: isдействительно классная вещь, когда вы хотите что-то сделать во время выполнения (например, вы определяете во время выполнения, какое именно сообщение вы хотите отправить объекту).Или вот пример из «реальной жизни»: UIButton имеет метод

- (void)addTarget:(id)target action:(SEL)action forControlEvents:(UIControlEvents)controlEvents

Таким образом, он хранит действие где-то во внутренних органах, а когда есть соответствующее управляющее событие, он вызывает:

[target performSelector: action];

NSOperation это просто хороший способ обернуть вашу работу с потоками.А NSThread - это просто оболочка для pthreads.

Таким образом, производительность вашего приложения не зависит от того, как вы используете потоки, однако это гораздо проще сделать с помощью NSOperation, а не pthreads.

7 голосов
/ 03 марта 2011

NSThread - это оболочка для pthreads (потоков POSIX).pthreads реализована поверх потока Маха.Вы можете установить размер стека, приоритет при использовании NSThread.(Кстати, насколько я знаю, размер стека вообще не влияет.)

NSOperation / NSOperationQueue - это оболочка для Grand Central Dispatch (libdispatch), также называемая GCD.GCD реализован поверх pthreads.Их легче использовать, чем NSThread для многих задач.Он уменьшает стандартный код для постановки в очередь задач, управления пулом потоков и т. Д.

executeSelectorInBackground: вызывает NSThread и обрабатывает завершенный NSThread.В них проще всего использовать только один метод.

3 голосов
/ 03 марта 2011

Короче говоря, вам не нужно работать с NSThread большую часть времени, особенно если вы работаете только с Objective-C, и проблема с синхронизацией не является критической.Реализуйте поведение, используя очередь операций или очередь отправки.

NSOperation - это оболочка или инкапсуляция определенной задачи.Задача может быть определена как метод (NSInvocationOperation), либо блок (NSBlockOperation), либо как угодно (путем создания подкласса NSOperation).Поэтому первое, что вам нужно сделать, - это обернуть свою работу соответствующим образом (обычно методом или блоком).

Затем вы поместите операцию в очередь операций.Затем очередь операций запустит задачу в отдельном потоке как можно скорее.

В iOS 4.0 и более поздних версиях вы можете напрямую передавать блок в очередь, не создавая объект операции.Также вы можете использовать различные типы очередей заданий, называемых очередями отправки.

executeSelectorinBackgroundThread похож на очереди, поскольку он также создает для вас поток и (эффективно) запускает метод в этом потоке.Иногда это может быть удобно, но вам все же нужно четко понимать блок задач, который будет выполняться в отдельном потоке.Многие методы Какао не являются поточно-ориентированными, и большинство операций UIKit должны выполняться в основном потоке.

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

[aUIObject executeSelectorOnMainThread: @selector (setMessage :) withData: ...

...