Реализовать механизм связывания сообщений в Objective-C?

Я пишу приложение, которое требует запуска метода после завершения другого метода. (Общий сценарий, верно?)

Я пытаюсь реализовать цепочечные методы. Лучшее, что я придумал, это позвонить performSelector:withObject:afterDelay:, Я просто не уверен, что это лучший способ сделать это. Я посмотрел, как игровой движок Cocos2d реализует его CCSequence класс, но я не уверен, что понимаю это.

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

Как реализовать механизм запуска методов один за другим? (Я открыт для использования таймеров или блоков, но я не знаю, как бы я использовал блоки в этом случае.)

Редактировать:

Чтобы уточнить, я пытаюсь реализовать такую ​​систему, как cocos2d CCSequence класс, который принимает несколько методов и "отправляет" их последовательно. Такие вещи, как анимация, для выполнения которой требуется больше, чем один тактовый цикл.

Я не собираюсь блокировать основной поток и не хочу жестко кодировать методы друг друга. Cocos2d имеет систему секвенирования, где я могу передавать методы в очередь и запускать их последовательно.

Изменить 2:

Кроме того, я хотел бы иметь возможность отменить мои запланированные очереди, и поэтому я не уверен, что GCD подходит для этого. Можно ли отменить последовательные очереди GCD?

5 ответов

Решение

Я наконец-то нашел то, что искал. Завершение блоков. Проще говоря, я бы написал такой метод:

- (void) performSomeActionWithCompletion:(void (^)()) completion{

     [self someAction];

     if(completion()){
       completion(); 
     }

}

Теперь я могу назвать свой метод так:

[self performSomeActionWithCompletion:^{
  NSLog(@"All done! (Well, not the async stuff, but at any rate...)");
}];

Вы можете использовать технику ThreadMigration

Тогда вот идет интересное задание под названием GCD-Grand Central Dispatch

Grand Central Dispatch (GCD) - это технология, разработанная Apple Inc. для оптимизации поддержки приложений для систем с многоядерными процессорами и другими симметричными многопроцессорными системами. Это реализация параллелизма задач на основе шаблона пула потоков.

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

Очереди отправки - это объекты, которые поддерживают очередь задач, либо блоки анонимного кода, либо функции, и выполняют эти задачи в свою очередь. Библиотека автоматически создает несколько очередей с разными уровнями приоритета, которые выполняют несколько задач одновременно, выбирая оптимальное количество задач для запуска в зависимости от операционной среды. Клиент библиотеки также может создавать любое количество последовательных очередей, которые выполняют задачи в порядке их отправки, по одной за раз. Поскольку последовательная очередь может выполнять только одну задачу за раз, каждая задача, переданная в очередь, является критической по отношению к другим задачам в очереди, и, таким образом, последовательная очередь может использоваться вместо блокировки конкурирующего ресурса.

Очереди отправки выполняют свои задачи одновременно с другими очередями отправки. Сериализация задач ограничивается задачами в одной очереди отправки.

В вашем случае вы можете использовать последовательные очереди отправки

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

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

dispatch_queue_t queue;

queue = dispatch_queue_create("com.example.MyQueue", NULL);

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

Grand Central Dispatch предоставляет функции, позволяющие вам получить доступ к нескольким общим очередям отправки из вашего приложения:

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

Используйте функцию dispatch_get_main_queue для получения очереди последовательной отправки, связанной с основным потоком вашего приложения. Эта очередь создается автоматически для приложений Какао и для приложений, которые либо вызывают функцию dispatch_main, либо настраивают цикл выполнения (используя либо тип CFRunLoopRef, либо объект NSRunLoop) в главном потоке.

Используйте функцию dispatch_get_global_queue, чтобы получить любую из совместно используемых очередей.

Примечание. Вам не нужно сохранять или освобождать какие-либо глобальные очереди отправки, включая параллельные очереди отправки или основную очередь отправки. Любые попытки сохранить или освободить очереди игнорируются.

Источник: Руководство по программированию параллелизма

Как насчет использования последовательной очереди GCD?

частные очереди отправки

Последовательные очереди (также известные как частные очереди отправки) выполняют одну задачу за раз в том порядке, в котором они добавляются в очередь. Выполняемая в данный момент задача выполняется в отдельном потоке (который может варьироваться от задачи к задаче), который управляется очередью отправки. Последовательные очереди часто используются для синхронизации доступа к определенному ресурсу. Вы можете создать столько последовательных очередей, сколько вам нужно, и каждая очередь работает одновременно по отношению ко всем другим очередям. Другими словами, если вы создаете четыре последовательных очереди, каждая очередь выполняет одновременно только одну задачу, но одновременно может выполняться до четырех задач, по одной из каждой очереди. Информацию о том, как создавать последовательные очереди, см. В разделе "Создание последовательных очередей отправки".

( источник)

Это было бы полезно, если вы хотите, чтобы все ваши сообщения обрабатывались в фоновом потоке.

Есть два метода executeSelector, которые могут ждать завершения, не нужно угадывать время.

[self performSelector:<#(SEL)#> onThread:<#(NSThread *)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];

[self performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>];

Похоже, вы хотите проверить NSOperationQueue, NSOperation, и либо NSBlockOperation или же NSInvocationOperation, В отличие от очереди GCD, NSOperationQueue поддерживает отмену заданий.

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

Начните с главы об очередях операций в Руководстве по программированию параллелизма.

Другие вопросы по тегам