IOS block編程指南 2 block開始 – iPhone手機開發技術文章 iPhone軟體開發教學課程

Getting Started with Blocks(開始block)

The following sections help you to get started with blocks using practical examples.

接下來這一節有實用的例子幫你開始blocks.

Declaring and Using a Block (定義和使用block)

You use the ^ operator to declare a block variable and to indicate the beginning of a block literal. The body of the block itself is contained within {}, as shown in this example (as usual with C, ; indicates the end of the statement):

你使用^操作定義一個block值同時表示瞭一個block的開始。block的主題被{}包圍,就像例子中展示的那樣(就像通常的C中,分號;申明瞭一個語句的結束):

 

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

The example is explained in the following illustration:

這個例子在下面的說面中得到瞭解釋:

../Art/blocks.jpg myBlock 的返回值是int類型的 。我們使用^聲明瞭一個myBlock的block。隻需要一個參數,也是int類型的。參數名是num。這是一個塊的定義,給myblock賦值。這是block的主體。

Notice that the block is able to make use of variables from the same scope in which it was defined.

If you declare a block as a variable, you can then use it just as you would a function:

註意block可以使用定義在block定義作用用中的變量。

如果你把block定義成瞭一個變量,你可以像使用函數一樣使用block。

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
 
printf(%d, myBlock(3));
// prints 21

Using a Block Directly(直接使用block)

In many cases, you don’t need to declare block variables; instead you simply write a block literal inline where it’s required as an argument. The following example uses the qsort_b function. qsort_b is similar to the standard qsort_r function, but takes a block as its final argument.

在很多情況下你不需要把block定義成一個變量;相反的你可以直接寫出一個block作為參數。下面的例子用到瞭qsort_b函數,qsort_b很類似標準的qsort_r函數,是指使用一個block作為一最後一個參數。

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 }

Blocks with Cocoa(cocoa中的block)

Several methods in the Cocoa frameworks take a block as an argument, typically either to perform an operation on a collection of objects, or to use as a callback after an operation has finished. The following example shows how to use a block with the NSArray methodsortedArrayUsingComparator:. The method takes a single argument—the block. For illustration, in this case the block is defined as anNSComparator local variable:

Cocoa 框架中有一些方法使用block作為一個參數,特別是對多個對象進行操作,或者在一個操作結束之後回調。下面的例子展示瞭NSArray怎樣在方法sortedArrayUsingComparator:中使用block。這個方法使用瞭一個參數——block。為瞭說明,這個block被定義為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 Variables(_block 類型變量)

A powerful feature of blocks is that they can modify variables in the same lexical scope. You signal that a block can modify a variable using the__block storage type modifier. Adapting the example shown in Blocks with Cocoa, you could use a block variable to count how many strings are compared as equal as shown in the following example. For illustration, in this case the block is used directly and uses currentLocale as a read-only variable within the block:

block的另一個強大的特性是可以修改同一詞法范圍的變量。你可以把一個block想修改的變量聲明成_block類型。改寫Blocks with Cocoa中的例子,你可以在下面的例子中使用block變量統計有多少字符串是相同的。為瞭說明需要,例子中直接使用block,同時把currentLocate作為一個block中的隻讀變量。

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,
    StrU00eeng 21,
    StriU00f1g 21
)
orderedSameCount: 2
*/

This is discussed in greater detail in Blocks and Variables.

更詳細的討論請看:Blocks and Variables.

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *