Как написать неблокирующий метод в target-c - PullRequest
2 голосов
/ 22 ноября 2011

Я хочу написать метод, который не блокирует.Метод ничего не возвращает.Это не через Интернет или что-то еще - все это локально для устройства, на котором оно работает.

По сути, вызывающий метод просто хочет, чтобы какой-то другой объект позаботился о чем-то.И как только он говорит: «Иди, сделай это», вызывающая сторона хочет вернуться к выполнению своей собственной работы, а не ждать, пока объект завершит выполнение задачи.

Я не хочу использовать NSNotification.

РЕДАКТИРОВАТЬ: я хочу быть в состоянии сделать это с помощью фреймворков, доступных на iOS 3.1.2 и более поздних версиях

РЕДАКТИРОВАТЬ: Спасибо за все великолепные ответы - но я не уверен в том, что выбрать.Мои требования состоят в том, чтобы вызывающий метод мог посылать аргументы вызываемому методу и возвращаться немедленно, не дожидаясь результата.Какое решение будет лучшим?

Ответы [ 5 ]

2 голосов
/ 22 ноября 2011

Я бы использовал GCD .

2 голосов
/ 22 ноября 2011

Вы используете одно из: libdispatch, NSOperation, добавление NSInvocation или «выполнение селектора в потоке» в цикл выполнения, создание потока ...

Обновление

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

Создать тему

Вы можете использовать pthread интерфейсы для создания одного или нескольких потоков для выполнения вашей работы.

Можно выбрать pthreads для максимальной производительности и контроля над любой опцией в списке. Относительно производительности: это требует, чтобы вы хорошо понимали затраты и проблемы. Создание потоков не тривиально, поэтому хорошо использовать их повторно или хорошо разделять задачи. Создание и тестирование параллельных проектов также занимает много времени.

Лично , я использую более переносимую абстракцию (особенно над pthreads) для большинства моих потребностей в многопоточности. Если важна переносимость, вы, вероятно, захотите использовать такой уровень абстракции, потому что остальные опции не видны за пределами систем Apple.

Вы также можете использовать что-то вроде -[NSObject performSelectorInBackground:withObject:] для удобства работы с типами объектов.

libdispatch

(a.k.a. GCD)

Хотя я читаю это не вариант для вас, я напишу краткий обзор независимо от того: может быть уподоблен уровню абстракции пула задач / планировщика / пула поверх pthreads. Эта библиотека часто используется для одновременных задач. Он использует пул потоков для задач, которые могут блокироваться или выполняться асинхронно. Довольно быстрая и простая абстракция и простота использования.

NSOperation

Интерфейс на основе задач (NSOperation) / пул + планировщик (NSOperationQueue), который теперь использует libdispatch. Это чувствует * на 1038 * больше задач, чем libdispatch. Он предшествовал libdispatch и имеет интерфейс ObjC. Однако в функциональности существует много общего. Довольно быстрая и простая абстракция и простота использования.

Добавить NSInvocation или «выполнить селектор в потоке» в цикл выполнения

Если ваша задача проста, вы, возможно, захотите использовать этот подход с минимальными издержками, просто указав объекту выполнить селектор или NSInvocation в определенном потоке. Система добавит его в список действий (для цикла выполнения указанного потока).

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

2 голосов
/ 22 ноября 2011

Есть несколько полезных методов для NSObject, которые могут вам помочь - этот, вероятно, самый:

[self performSelectorInBackground:@selector(doStuff) withObject:nil];


- (void)doStuff {
    // Do whatever you want to do here. It's in the background.
}

Однако это предполагает, что вы не хотите отменять фоновую задачу - вы также должны посмотреть NSOperation и NSOperationQueue , если вам нужно больше контроля.

1 голос
/ 22 ноября 2011

Используйте NSThread s detachNewThreadSelector:toTarget:withObject:.

0 голосов
/ 08 декабря 2014

Этот маленький персик работал на меня (чтобы задержать на 20 секунд) ....

CFRunLoopRunInMode(kCFRunLoopDefaultMode, 20.0, false);
...