天天看點

iOS block學習

下面這個連結寫的block不錯。

http://lldong.github.io/blog/2011/12/30/blocks/

轉自:http://blog.csdn.net/yhawaii/article/details/7556739

iOS4已經直接支援blocks,很有必要學習一下。

在ios,blocks是對象,它封裝了一段代碼,這段代碼可以在任何時候執行。Blocks可以作為函數參數或者函數的傳回值,而其本身又可以帶輸入參數或傳回值。它和傳統的函數指針很類似,但是有差別:blocks是inline的,并且它對局部變量是隻讀的。

Blocks的定義:

[cpp] view plaincopy

  1. int (^myBlock) (int a,int b) = ^(int a,int b){  
  1.        return a+b;  
  1.    };  

[cpp] view plaincopy

  1. int num = 0;  
  1.     //使用block  
  1.     int (^myBlock) (int a,int b) = ^(int a,int b){  
  1.         num = a+b;  
  1.         return num;  
  1.     };  

[cpp] view plaincopy

  1. __block int num = 0;  
  1.     //使用block  
  1.     int (^myBlock) (int a,int b) = ^(int a,int b){  
  1.         num = a+b;  
  1.         return num;  
  1.     };  

定義了一個名為myBlock的blocks對象,它帶有兩個int參數,傳回int。等式右邊就是blocks的具體實作,是不是有點像方法的定義?

Blocks可以通路局部變量,但是不能修改。比如下面的代碼就會報編譯錯 

如果要修改就要加關鍵字:__block (注意,是兩個下劃線"_")

作為函數的參數,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"

)

關于blocks更詳細的資訊可參見:http://bukkake.iteye.com/blog/1168602

iOS