iOS4已經直接支持blocks,很有必要學習一下。
在ios,blocks是對象,它封裝了一段代碼,這段代碼可以在任何時候執行。Blocks可以作為函數參數或者函數的返回值,而其本身又可以帶輸入參數或返回值。它和傳統的函數指針很類似,但是有區別:blocks是inline的,並且它對局部變量是只讀的。
Blocks的定義:
int (^myBlock) (int a,int b) = ^(int a,int b){
return a+b;
};
定義了一個名為myBlock的blocks對象,它帶有兩個int參數,返回int。等式右邊就是blocks的具體實現,是不是有點像方法的定義?
Blocks可以訪問局部變量,但是不能修改。比如下面的代碼就會報編譯錯
int num = 0;
//使用block
int (^myBlock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
如果要修改就要加關鍵字:__block (注意,是兩個下劃線"_")
__block int num = 0;
//使用block
int (^myBlock) (int a,int b) = ^(int a,int b){
num = a+b;
return num;
};
作為函數的參數,blocks某種意義上替代了回調函數或者delegate。當函數調用了,假設某個事件觸發,這時blocks裡的內容就會運行。這樣有利於代碼的整合和閱讀,你不需要到處去實現委托方法了。
系統API中已經有很多支持blocks參數了
· Completion handlers
· Notification handlers
· Error handlers
· Enumeration
· View animation and transitions
· Sorting
例如:
[UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)())animations]
集合體中也可以運用blocks。枚舉一個數組時我們通常:
for (id obj in Array);
現在,
NSString *area = @"Europe";
NSArray *timeZoneNames = [NSTimeZone knownTimeZoneNames];
NSMutableArray *areaArray = [NSMutableArray arrayWithCapacity:1];
NSIndexSet *areaIndexes = [timeZoneNames indexesOfObjectsWithOptions:NSEnumerationConcurrent
passingTest:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *tmpStr = (NSString *)obj;
return [tmpStr hasPrefix:area];
}];
NSArray *tmpArray = [timeZoneNames objectsAtIndexes:areaIndexes];
[tmpArray enumerateObjectsWithOptions:NSEnumerationConcurrent|NSEnumerationReverse
usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
[areaArray addObject:[obj substringFromIndex:[area length]+1]];
}];
NSLog(@"Cities in %@ time zone:%@", area, areaArray);
在blocks中obj就是數組中的每個成員,我們就可以在blocks內對每個對象進行處理。再比如:
NSMutableArray *mArray = [NSMutableArray arrayWithObjects:@"a",@"b",@"abc",nil];
NSMutableArray *mArrayCount = [NSMutableArray arrayWithCapacity:1];
[mArray enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock: ^(id obj,NSUInteger idx, BOOL *stop){
[mArrayCount addObject:[NSNumber numberWithInt:[obj length]]];
}];
NSLog(@"%@",mArrayCount);
你會發現,這樣寫代碼更容易讀懂。
最後,看一個排序的例子:
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 finderSort = ^(id string1, id string2) {
NSRange string1Range = NSMakeRange(0, [string1 length]);
return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];
};
NSLog(@"finderSort: %@", [stringsArray sortedArrayUsingComparator:finderSort]);
結果:finderSort: (
"string 1",
"String 02",
"String 11",
"string 12",
"String 21"
)