РЕДАКТИРОВАТЬ: не вдаваясь в подробности, теперь в ARC вы можете добавлять блоки в коллекции, как и любой другой объект (см. Обсуждение).
Я оставил исходный ответ без изменений, поскольку он содержит некоторые интересные технические детали.
Возникает вопрос, являются ли блоки первоклассными объектами или они
просто относиться как к объектам ради передачи их между
объекты? Если они являются объектами первого класса, то не должны ли они быть
хранится в массивах?
Блоки - это объекты Objective-C, которые очень похожи на любой другой объект NSO, с парой ключевых отличий:
Блоки всегда генерируются компилятором. Они фактически «alloc / init» редактируются во время выполнения, поскольку выполнение проходит через объявление блоков.
Блоки изначально создаются в стеке. Block_copy () или copy
метод должен использоваться для перемещения блока в кучу, если блок должен пережить текущую область (см. Точку ARC ниже).
У блоков на самом деле нет вызываемого API, кроме управления памятью.
Чтобы поместить блок в коллекцию, его сначала нужно скопировать . Всегда. В том числе по ARC. (см. Комментарии.) Если вы этого не сделаете, есть риск, что выделенный стеку блок будет autoreleased
, и ваше приложение позже будет аварийно завершено.
Копирование блока на основе стека копирует также все захваченное состояние. Если вы делаете несколько копий блока, более эффективно скопировать его один раз, а затем скопировать копию (потому что копирование копии просто увеличивает количество сохраняемых элементов, поскольку блоки являются неизменяемыми).
В ARC возврат блока из метода или функции "просто работает"; оно будет автоматически скопировано в кучу, и возвращение будет автоматически освобожденным блоком (компилятор может оптимизировать автоматическое освобождение при определенных обстоятельствах). Даже с ARC вам все равно нужно скопировать блок, прежде чем вставить его в коллекцию.
Я написал пару постов в блоге, в которых содержится введение в блоки и некоторые советы и рекомендации . Вы можете найти их интересными.
И, да, добавление их в словари весьма полезно. Я написал пару кусочков кода, где я помещал блоки в словари как обработчики команд, где ключом было имя команды. Очень удобно.