天天看點

iOS開發之使用block塊進行資料周遊的方法

看了一篇文章,發現周遊數組、字典中的資料時,除了使用for循環外,還可以使用block塊進行操作,瞬間感覺iOS的語言代碼确實有點高大上的感覺,下面就簡單的介紹一下這個方法。

首先是最基本的運用形式,

//基于 塊(block) 結構的周遊數組方法  enumerate:列舉,數

    //參數介紹: obj:值  idx:索引  stop:停止周遊

    NSArray *arr1 = @[@"好", @"好", @"學", @"習", @"天", @"天", @"向",@"上"];

    [arr1 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

        //NSLog(@"輸出基于 塊(block) 結構的周遊數組方法數組中的值.......%@", obj);

        if ([obj isEqualToString:@"習"]) {

            *stop = YES;

        }

    }];

    //基于 塊(block) 結構的周遊字典方法,字典是無序的,每次值的順序是不固定的  enumerate:列舉,數

    //參數介紹: key:鍵  obj:值  stop:停止周遊

    NSDictionary *dict1 = @{@"1":@"好好", @"2":@"學習", @"3":@"天天",@"4":@"向上"};

    [dict1 enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

        //NSLog(@"輸出基于 塊(block) 結構的周遊字典方法字典中的值........%@", obj);

        if ([obj isEqualToString:@"向上"]) {

            *stop = YES;

        }

    }];

若已知collection裡對象的資料類型,可以修改塊簽名,知道對象的精确類型後,編譯器就可以檢測開發者是否調用了該對象所不具有的方法,并在發現問題時報錯。

如代碼,直接把key和value的類型修改成NSString類型。

//基于 塊(block) 結構的周遊字典,如果知道字典中的鍵、值類型,可以修改塊兒中的鍵、值類型的方法,字典是無序的,每次值的順序是不固定的  enumerate:列舉,數

    //參數介紹: key:鍵  obj:值  stop:停止周遊

    NSDictionary *dict2 = @{@"1":@"好好", @"2":@"學習", @"3":@"天天",@"4":@"向上"};

    [dict2 enumerateKeysAndObjectsUsingBlock:^(NSString *key, NSString *obj, BOOL * _Nonnull stop) {

        //NSLog(@"基于 塊(block) 結構的周遊字典,修改鍵、值類型的方法字典中的值........%@", obj);

        if ([obj isEqualToString:@"向上"]) {

            *stop = YES;

        }

    }];

//基于 塊(block) 結構的 反向 周遊數組方法  enumerate:列舉,數   多添加一個參數:NSEnumerationReverse:Reverse:相反,

    //參數介紹: obj:值  idx:索引  stop:停止周遊

    NSArray *arr2 = @[@"好", @"好", @"學", @"習", @"天", @"天", @"向",@"上"];

    [arr2 enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {

        //NSLog(@"基于 塊(block) 結構的 反向 周遊數組方法數組中的值.......%@", obj);

        if ([obj isEqualToString:@"習"]) {

            *stop = YES;

        }

    }];

//基于 塊(block) 結構的 并發 周遊數組方法  enumerate:列舉,數  Concurrent:同時發生的

    //參數是:NSEnumerationConcurrent,也就是可以同時周遊collection中的幾個元素,具體數量根據系統資源而定

    //參數介紹: obj:值  idx:索引  stop:停止周遊

    NSArray *arr3 = @[@"好", @"好", @"學", @"習", @"天", @"天", @"向",@"上"];

    NSMutableArray *newArr = [NSMutableArray arrayWithArray:arr3];

    [newArr enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString *obj, NSUInteger idx, BOOL * _Nonnull stop) {

        obj = [NSString stringWithFormat:@"_%@", obj];

        [newArr replaceObjectAtIndex:idx withObject:obj];

        NSLog(@"基于 塊(block) 結構的 并發 周遊數組方法數組中的值.......%@", obj);

//        if ([obj isEqualToString:@"_向"]) {

//            *stop = YES;

//        }

    }];

優缺點總結:

優點:

1、可以完美實作for循環的所有功能;

2、可以友善擷取集合中的每一項元素;

3、提供了循環周遊的參數,NSEnumerationReverse用來實作倒序循環。NSEnumerationConcurrent用來實作并發周遊,兩個參數可以同時使用;

4、這種循環方式效率高,能夠提升程式性能,開發者可以專注于業務邏輯,而不必擔心記憶體和線程的問題;

5、當開啟NSEnumerationConcurrent選項時,可以實作for循環和快速周遊無法輕易實作的并發循環功能,系統底層會通過GCD處理并發事宜,這樣可以充分利用系統和硬體資源,達到最優的周遊效果;

6、可以修改塊簽名,當我們已經明确集合中的元素類型時,可以把預設的簽名id類型修改成已知類型,比如常見的NSString,這樣既可以節省系統資源開銷,也可以防止誤向對象發送不存在的方法是引起的崩潰。

缺點:

1、很多開發者不知道這種周遊方式;

2、這裡使用了block,需要注意在block裡容易引起的保留環問題,比如使用self調用方法時,把self轉化成若引用即可打破保留環。如:__weak __typeof(self)weakSelf = self 或者 __weak MyController *weakSelf = self; 在block裡使用weakSelf即可。

注意:

使用基于塊的周遊時是可以修改周遊的元素的,不會導緻崩潰,但是如果要删除周遊的元素會導緻後面的元素無法周遊而崩潰,解決辦法有2種,1、一種是複制一份原集合的副本,對副本進行操作,找出所要操作的元素後再處理原集合;2、使用反向周遊,反向周遊删除元素後不會導緻崩潰。

參考文獻,原文連結:http://www.jianshu.com/p/d6ef96c862ca

繼續閱讀