Начало работы с блоками
Следующие разделы помогают Вам начать с блоками с помощью практических примеров.
Объявляя и Используя блок
Вы используете ^
оператор, чтобы объявить основную переменную и указать начало блочного литерала. Организация самого блока содержится в {}
, как показано в этом примере (как обычно, с C, ;
указывает конец оператора):
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
Пример объяснен на следующей иллюстрации:
Заметьте, что блок в состоянии использовать переменные от того же объема, в котором он был определен.
Если Вы объявляете блок как переменную, можно тогда использовать его так же, как Вы были бы функция:
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
printf("%d", myBlock(3)); |
// prints "21" |
Используя блок непосредственно
Во многих случаях Вы не должны объявлять основные переменные; вместо этого Вы просто пишете блочный литерал, встроенный, где он требуется как параметр. Следующий пример использует qsort_b
функция. qsort_b
подобно стандарту qsort_r
функция, но берет блок в качестве его заключительного параметра.
char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" }; |
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) { |
char *left = *(char **)l; |
char *right = *(char **)r; |
return strncmp(left, right, 1); |
}); |
// myCharacters is now { "Charles Condomine", "George", "TomJohn" } |
Блоки с какао
Несколько методов в Какао платформы берут блок в качестве параметра, обычно или чтобы выполнить работу на наборе объектов или использовать в качестве обратного вызова после того, как закончилась работа. Следующий пример показывает, как использовать блок с NSArray
метод sortedArrayUsingComparator:
. Метод берет отдельный аргумент — блок. Для иллюстрации в этом случае блок определяется как NSComparator
локальная переменная:
NSArray *stringsArray = @[ @"string 1", |
@"String 21", |
@"string 12", |
@"String 11", |
@"String 02" ]; |
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch | |
NSWidthInsensitiveSearch | NSForcedOrderingSearch; |
NSLocale *currentLocale = [NSLocale currentLocale]; |
NSComparator finderSortBlock = ^(id string1, id string2) { |
NSRange string1Range = NSMakeRange(0, [string1 length]); |
return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale]; |
}; |
NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock]; |
NSLog(@"finderSortArray: %@", finderSortArray); |
/* |
Output: |
finderSortArray: ( |
"string 1", |
"String 02", |
"String 11", |
"string 12", |
"String 21" |
) |
*/ |
__ основные переменные
Мощная функция блоков - то, что они могут изменить переменные в том же лексическом контексте. Вы сигнализируете, что блок может изменить переменную с помощью __block
модификатор типа хранения. Адаптируя пример, показанный в Блоках с Какао, Вы могли использовать основную переменную для подсчета, сколько строк сравнено столь же равные как показано в следующем примере. Для иллюстрации в этом случае блок используется непосредственно и использование currentLocale
как переменная только для чтения в блоке:
NSArray *stringsArray = @[ @"string 1", |
@"String 21", // <- |
@"string 12", |
@"String 11", |
@"Strîng 21", // <- |
@"Striñg 21", // <- |
@"String 02" ]; |
NSLocale *currentLocale = [NSLocale currentLocale]; |
__block NSUInteger orderedSameCount = 0; |
NSArray *diacriticInsensitiveSortArray = [stringsArray sortedArrayUsingComparator:^(id string1, id string2) { |
NSRange string1Range = NSMakeRange(0, [string1 length]); |
NSComparisonResult comparisonResult = [string1 compare:string2 options:NSDiacriticInsensitiveSearch range:string1Range locale:currentLocale]; |
if (comparisonResult == NSOrderedSame) { |
orderedSameCount++; |
} |
return comparisonResult; |
}]; |
NSLog(@"diacriticInsensitiveSortArray: %@", diacriticInsensitiveSortArray); |
NSLog(@"orderedSameCount: %d", orderedSameCount); |
/* |
Output: |
diacriticInsensitiveSortArray: ( |
"String 02", |
"string 1", |
"String 11", |
"string 12", |
"String 21", |
"Str\U00eeng 21", |
"Stri\U00f1g 21" |
) |
orderedSameCount: 2 |
*/ |
Это обсуждено более подробно в Блоках и Переменных.