Начало работы с блоками

Следующие разделы помогают Вам начать с блоками с помощью практических примеров.

Объявляя и Используя блок

Вы используете ^ оператор, чтобы объявить основную переменную и указать начало блочного литерала. Организация самого блока содержится в {}, как показано в этом примере (как обычно, с C, ; указывает конец оператора):

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};

Пример объяснен на следующей иллюстрации:

../Art/blocks.jpg

Заметьте, что блок в состоянии использовать переменные от того же объема, в котором он был определен.

Если Вы объявляете блок как переменную, можно тогда использовать его так же, как Вы были бы функция:

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
*/

Это обсуждено более подробно в Блоках и Переменных.