首页 > 代码库 > Blocks Programming Topics

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 = [stringsArraysortedArrayUsingComparator:^(id string1, id string2) {
    NSRange string1Range = NSMakeRange(0, [string1 length]);
    NSComparisonResult comparisonResult = [string1 compare:string2options: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",

"Str\U00eeng 21",
      "Stri\U00f1g 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 

你可以

 

 

 

 

 

 

Blocks Programming Topics