Блочный объект
Блочными объектами является C-уровень синтаксическая и функция во время выполнения, которые позволяют Вам составлять выражения function, которые могут быть переданы как параметры, дополнительно сохранили и использовали многократными потоками. Выражение function может сослаться и может сохранить доступ к локальным переменным. На других языках и средах, блочный объект иногда также вызывают закрытием или лямбдой. Вы используете блок, когда Вы хотите создать единицы работы (т.е. сегменты кода), который может быть роздан, как будто они - значения. Блоки предлагают более гибкое программирование и больше питания. Вы могли бы использовать их, например, чтобы записать обратные вызовы или выполнить работу на всех элементах в наборе.
Объявление блока
Во многих ситуациях Вы используете блоки, встроенные, таким образом, Вы не должны объявлять их. Синтаксис объявления, однако, подобен стандартному синтаксису для указателей функции, за исключением того, что Вы используете каре (^) вместо указателя звездочки (*). Например, следующее объявляет переменную aBlock
это ссылается на блок, требующий трех параметров и возвращающий a float
значение:
float (^aBlock)(const int*, int, float); |
Создание блока
Вы используете каре (^
) оператор для указания начала и точки с запятой для указания конца блочного выражения. Следующий пример объявляет простой блок и присваивает его ранее заявленной основной переменной (oneFrom
):
int (^oneFrom)(int); |
oneFrom = ^(int anInt) { |
return anInt - 1; |
}; |
Заключительная точка с запятой требуется как стандарт C маркер конца строки.
Если Вы явно не объявляете возвращаемое значение блочного выражения, оно может быть автоматически выведено из содержания блока.
Непостоянные блоком переменные
Можно использовать __block
модификатор хранения с переменными объявил локально к лексическому контексту включения, чтобы обозначить, что такие переменные должны быть предоставленными ссылкой в блоке и являются непостоянными - также. Любые изменения отражаются в лексическом контексте включения, включая любые другие блоки, определенные в том же лексическом контексте включения.
Используя блоки
Если Вы объявляете блок как переменную, можно использовать его, поскольку Вы были бы функция. Следующий пример распечатывает 9, как выведено.
printf("%d\n", oneFrom(10)); |
Как правило, однако, Вы передаете блок как параметр функции или методу. В этих случаях Вы часто создаете встроенный блок.
Следующий пример определяет ли NSSet
объект содержит слово, указанное локальной переменной, и устанавливает значение другой локальной переменной (found
) к YES
(и останавливает поиск), если он делает. В этом примере, found
объявляется как a __block
переменная.
__block BOOL found = NO; |
NSSet *aSet = [NSSet setWithObjects: @"Alpha", @"Beta", @"Gamma", @"X", nil]; |
NSString *string = @"gamma"; |
[aSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { |
if ([obj localizedCaseInsensitiveCompare:string] == NSOrderedSame) { |
*stop = YES; |
found = YES; |
} |
}]; |
// At this point, found == YES |
В этом примере блок содержится в списке аргументов метода. Блок также использует локальную переменную штабеля.
Операции сравнения
Одна из более общих операций, которые Вы выполняете с блоками в среде Какао, является сравнением двух объектов — для сортировки содержания массива, например. Время выполнения Objective C определяет тип блока —NSComparator
— использовать для этих сравнений.