zoukankan      html  css  js  c++  java
  • Blocks Programming Topics

    Getting Started with Blocks 

    Declaring and Using a Block 

    使用^操作符来声明一个block变量并且指明了block的开始。body在{}中如下的例子:

    int multiplier = 7;

    int (^myBlock)(int) = ^(int num) {

    return num * multiplier;
    };
    };
    

    例子解释如下:

    你可以看到block body中可以访问 {}和自己是同一个scope的变量。

    如果你将block声明为一个变量,那么你可以像函数一样使用它,例如:

      int multiplier = 7;
    
      int (^myBlock)(int) = ^(int num) {
    
          return num * multiplier;
    
      };
    
      printf("%d", myBlock(3));
    
    //prints "21"

    Using a Block Directly 

    许多情况下你不需要声明block变量,而是简单写block inline作为参数。如下的例子使用qsort_b函数。qsort_b和标准的qsort_r函数很类似,但是将block作为了参数。

    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" }
    

    Blocks with Cocoa 

    如下的例子展示的就是如何使用block和nsarray方法sortedArrayUsingComparator:这个方法有一个block的参数。为了说明,这里将block定义成了NSComparator local 变量。

    NSArray *stringsArray = @[ @"string 1",
                                 @"String 21",
                                 @"string 12",
                                 @"String 11",
    
                                 @"String 02" ];
    
    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);

      /*
      Output:
      finderSortArray: (
    
          "string 1",
          "String 02",
          "String 11",
          "string 12",
          "String 21"
    

    ) */ 

    __block Variables 

    __block类型就说明了这个变量在block body中可以被改变。

      NSArray *stringsArray = @[ @"string 1",
    
    @"String 21", // <-
    @"string 12",
    @"String 11",
    @"Strîng 21", // <-
    @"Striñg 21", // <-
    @"String 02" ];
    
    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);
    

    /* Output:

    diacriticInsensitiveSortArray: (
        "String 02",
    
    "string 1",
    "String 11",
    "string 12",
    "String 21",

    "StrU00eeng 21",
          "StriU00f1g 21"
      )
    
      orderedSameCount: 2
      */

    Conceptual Overview 

    Block Functionality 

    • block 是一个匿名的code的inline collection
    • 有一个类似function的类型参数
    • 有一个返回类型
    • 可以捕获它定义范围内的状态
    • 可以有选择的改变定义范围内的状态
    • 可以在定义范围销毁后继续共享和改变定义状态

    Usage 

    blocks代表了小规模的,自容的代码片段。它们在执行并发的任务时作为封装单元尤其重要。block有别于传统callback函数的优点是:

    1,它们允许你在方法执行后的某一个调用的地方书写代码

    2,它们允许访问本地变量

    Declaring and Creating Blocks 

    Declaring a Block Reference 

    void (^blockReturningVoidWithVoidArgument)(void);

    int (^blockReturningIntWithIntAndCharArguments)(int, char);

    void (^arrayOfTenBlocksReturningVoidWithIntArgument[10])(int);

    没有返回类型的block必须显示表明为void类型

    你也可以创建block类型当你在多个地方使用特定的signature

    typedef float (^MyBlockType)(float, float);
    
    MyBlockType myFirstBlock = // ... ;
    MyBlockType mySecondBlock = // ... ;
    

    Creating a Block 

    以下的例子定义了一个简单的block然后分配给了一个之前声明的变量oneFrom。

    float (^oneFrom)(float);
    
    oneFrom = ^(float aFloat) {
        float result = aFloat - 1.0;
        return result;
    

    }; 

    Global Blocks 

    #import <stdio.h>
    
    int GlobalInt = 0;
    int (^getGlobalInt)(void) = ^{ return GlobalInt; };
    

    Blocks and Variables 

    5中类型的变量

    • global variables, including static locals
    • global functions
    • local variables and parameters form an enclosing scope
    • __block varibales
    • const improts

    Object and Block Variables 

    Objective-C Objects 

    当copy一个block时,它会创建一个object变量的强引用。如果你在一个执行方法中说使用block:

    如果你通过引用来访问一个实例变量,就会产生self的强引用

    如果你通过值来访问一个实例变量,就会产生这个变量的强引用

    dispatch_async(queue, ^{
          // instanceVariable is used by reference, a strong reference is made to self
          doSomethingWithObject(instanceVariable);
    

    });

      id localVariable = instanceVariable;
      dispatch_async(queue, ^{
    
          /*
            localVariable is used by value, a strong reference is made to localVariable
            (and not to self).
    

    */

          doSomethingWithObject(localVariable);
      });
    

    Using Blocks 

    Invoking a Block 

    如果你将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
    

    Using a Block as a Function Argument 

    你可以将block作为一个function参数进行传递。在大多数时候,你不需要声明blocks,只需要简单以内连形式来执行就可以了。以下的例子:

    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);
    
    });
    // Block implementation ends at "}"
    
    // myCharacters is now { "Charles Condomine", "George", "TomJohn" }
    
    下面的例子展示了如何在dispatch_apply函数中使用block。
    void dispatch_apply(size_t iterations, dispatch_queue_t queue, void
    (^block)(size_t));
    
    函数提交一个block到dispatch queue中。有三个参数。
    
    
    #include <dispatch/dispatch.h>
    
    size_t count = 10;
    

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_apply(count, queue, ^(size_t i) {
        printf("%u
    ", i);
    

    }); 

    ###################################################

    void func(void (^)(void));

    int main(int argc, const char * argv[]) {

        @autoreleasepool {

            void (^hw)(void) = ^{NSLog(@"hellow world!");};

            func(hw);

        }

        return 0;

    }

    void func(void (^b) (void))

    {

        NSLog(@"going to invoke the passed in block now.");

        b();

    }

    最后打印的结果为:

    2015-01-07 14:41:38.296 FunWithBlocks[539:69766] going to invoke the passed in block now.

    2015-01-07 14:41:38.298 FunWithBlocks[539:69766] hellow world!

    Using a Block as a Method Argument 

    cocoa提供了一系列使用blocks的方法。你传递block作为方法参数。例子:

    NSArray *array = @[@"A", @"B", @"C", @"A", @"B", @"Z", @"G", @"are", @"Q"];
    NSSet *filterSet = [NSSet setWithObjects: @"A", @"Z", @"Q", nil];
    
    BOOL (^test)(id obj, NSUInteger idx, BOOL *stop);
    test = ^(id obj, NSUInteger idx, BOOL *stop) {
    
        if (idx < 5) {
            if ([filterSet containsObject: obj]) {
    

    return YES; }

    }

    return NO; };

    NSIndexSet *indexes = [array indexesOfObjectsPassingTest:test];
    NSLog(@"indexes: %@", indexes);
    

    /* Output:

    indexes: <NSIndexSet: 0x10236f0>[number of indexes: 2 (in 2 ranges), indexes: (0
    3)]
    

    */ 

    Copying Blocks 

    其实你不需要copy一个block。只有当你想在scope destruction之后仍然想使用block的时候才会用到。copying将block移动到heap中。

    Block_copy();
    Block_release();
    

    Debugging 

    你可以在blocks中设置断点和单步跟踪。

    You can set breakpoints and single step into blocks. You can invoke a block from within a GDB session using invoke-block, as illustrated in this example:

    If you want to pass in a C string, you must quote it. For example, to pass this string into the doSomethingWithString block, you would write the following:

    page23image9664 page23image9824 page23image9984 page23image10144
    $ invoke-block myBlock 10 20page23image10912page23image11072page23image11232page23image11392
    $ invoke-block doSomethingWithString ""this string""
  • 相关阅读:
    前端面试题
    【429】关于ADT的访问权限
    【428】Dijkstra 算法
    【427】Graph 实现 以及 DFS & BFS
    【426】C 传递数组给函数
    【425】堆排序方法(二叉堆)优先队列(PQ)
    Hadoop案例(九)流量汇总案例
    Hadoop案例(八)辅助排序和二次排序案例(GroupingComparator)
    Hadoop案例(七)MapReduce中多表合并
    Hadoop案例(六)小文件处理(自定义InputFormat)
  • 原文地址:https://www.cnblogs.com/lisa090818/p/4207922.html
Copyright © 2011-2022 走看看