標籤:http io ar os 使用 sp for on div
在ios4之後,引入了代碼塊的特性,在gcd中會經常的用到,所以決定好好的看看代碼塊文檔,把這塊總結一下。從頭開始講解代碼塊。
1.聲明和使用代碼塊一般用^操作符聲明一個塊變數,並作為塊的開始符。而塊的本身用{}包括起來,就像下面那樣。
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
int(^myblocks)(int)=(^int num){return num * multiplier}; 其實意思就是前半句聲明了一個名字為myBlock的代碼塊,有一個int類型的參數,並返回一個int類型的值;後面的半句就是一個塊的定義,然後賦值給myBlock。 如果我們像上面那樣,聲明一個塊像一個變數一樣,我們就可以像使用函數一樣使用它,如下:
int multiplier = 7; |
int (^myBlock)(int) = ^(int num) { |
return num * multiplier; |
}; |
|
printf("%d", myBlock(3)); |
// prints "21" |
2.直接使用block在大多數情況下,我們不需要去聲明一個塊變數,我們直接寫一個簡單的代碼塊作為參數傳遞就行。下面的代碼函數qsort_b的第三個參數就是一個代碼塊。
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" } |
一些cocoa frameworks的方法採用一個block作為一個參數,典型的是對一個集合對象進行操作,或者是在一個操作完成之後使用回調。下面的例子是NSArray類的方法sortedArrayUsingComparator:怎樣使用一個block。此方法使用一個block作為一個參數。
NSArray *stringsArray = [NSArray arrayWithObjects: |
@"string 1", |
@"String 21", |
@"string 12", |
@"String 11", |
@"String 02", nil]; |
|
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); |
|
|
block的一個強大的功能是可以修改同一作用雨的變數,我們只需要在變數的前面加上一個_block標識符。下面的例子和上面的相同,只是添加功能用於記錄相同元素的個數。
NSArray *stringsArray = [NSArray arrayWithObjects: |
@"string 1", |
@"String 21", // <- |
@"string 12", |
@"String 11", |
@"Strîng 21", // <- |
@"Striñg 21", // <- |
@"String 02", nil]; |
|
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); |
|
|
3.block變數的聲明block的聲明和函數指標差不多,只是把*改為了^
void (^blockReturningVoidWithVoidArgument)(void); |
int (^blockReturningIntWithIntAndCharArguments)(int, char); |
void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int); |
也可以使用typedef去聲明block,方便以後使用,如下:
typedef float (^MyBlockType)(float, float); |
|
MyBlockType myFirstBlock = // ... ; |
MyBlockType mySecondBlock = // ... ; |
4.變數的範圍對於其在塊中的影響:
_block int x = 123; // x lives in block storage |
|
void (^printXAndY)(int) = ^(int y) { |
|
x = x + y; |
printf("%d %d\n", x, y); |
}; |
printXAndY(456); // prints: 579 456 |
// x is now 579 |
extern NSInteger CounterGlobal; |
static NSInteger CounterStatic; |
|
{ |
NSInteger localCounter = 42; |
__block char localCharacter; |
|
void (^aBlock)(void) = ^(void) { |
++CounterGlobal; |
++CounterStatic; |
CounterGlobal = localCounter; // localCounter fixed at block creation |
localCharacter = ‘a‘; // sets localCharacter in enclosing scope |
}; |
|
++localCounter; // unseen by the block |
localCharacter = ‘b‘; |
|
aBlock(); // execute the block |
// localCharacter now ‘a‘ |
} |
5.使用blocks(1)調用一個聲明好的block
int (^oneFrom)(int) = ^(int anInt) { |
return anInt - 1; |
}; |
|
printf("1 from 10 is %d", oneFrom(10)); |
// Prints "1 from 10 is 9" |
|
float (^distanceTraveled) (float, float, float) = |
^(float startingSpeed, float acceleration, float time) { |
|
float distance = (startingSpeed * time) + (0.5 * acceleration * time * time); |
return distance; |
}; |
|
float howFar = distanceTraveled(0.0, 9.8, 1.0); |
// howFar = 4.9 |
objective c 代碼塊blocks完整總結一