zoukankan      html  css  js  c++  java
  • objective c 代码块blocks完整总结一

    在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
    ", 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
  • 相关阅读:
    [LeetCode 1029] Two City Scheduling
    POJ 2342 Anniversary party (树形DP入门)
    Nowcoder 106 C.Professional Manager(统计并查集的个数)
    2018 GDCPC 省赛总结
    CF 977 F. Consecutive Subsequence
    Uva 12325 Zombie's Treasure Chest (贪心,分类讨论)
    Poj 2337 Catenyms(有向图DFS求欧拉通路)
    POJ 1236 Network of Schools (强连通分量缩点求度数)
    POJ 1144 Network (求割点)
    POJ 3310 Caterpillar(图的度的判定)
  • 原文地址:https://www.cnblogs.com/transcendent/p/4149159.html
Copyright © 2011-2022 走看看