• 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
  • 相关阅读:
    使用ffmpeg将mp4切片成ts slice 并生成m3u8命令,同时让IIS支持支持 m3u8
    C# 自动下移动光标 。winform 发送tab,在WPF中
    C# 获取当前程序路径方法整理
    Jeecg-Boot 2.0.0 版本发布,基于Springboot+Vue 前后端分离快速开发平台
    vue2.0源码-丰富的选项合并策略
    JavaScript 核心原理精讲
    前端性能优化
    Vue Router模式
    css3实现圆角三角形
    CSS动画
  • 原文地址:https://www.cnblogs.com/transcendent/p/4149159.html
Copyright © 2020-2023  润新知