zoukankan      html  css  js  c++  java
  • enumerateKeysAndObjectsUsingBlock 的用法

    block是一个有序列的指令代码块,通常在代码中间花括号括起来的objective-c代码,但是它能被传递和被分配局部变量,然后作为一个参数来传递,基本上可以把花括号中间的代码保存到数据结构里。看起来就像这样子:
      

    1. [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { NSLog(@“value for key %@ is %@”, key, value); if ([@“ENOUGH” isEqualToString:key]) { *stop = YES; }}];
    复制代码


      NSDictionary有一个方法叫enumerateKeysAndObjectsUsingBlock,它就一个参数就是block,这个block携带了三个参数,这将要把dictionary里面的key和value每次一组传递到block,enumerateKeysAndObjectsUsingBlock会遍历dictionary并把里面所有的key和value一组一组的展示给你,每组都会执行这个block。这其实就是传递一个block到另一个方法,在这个例子里它会带着特定参数被反复调用,直到找到一个ENOUGH的key,然后就会通过重新赋值那个BOOL *stop来停止运行,停止遍历同时停止调用block。

      ^表示这是一个block。在enumerateKeysAndObjectsUsingBlock之前定义一个局部变量,可以在block里使用,但它们都是只读的。
     

    1.  BOOL stoppedEarly = NO;double stopValue = 53.5;[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { NSLog(@“value for key %@ is %@”, key, value); if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) { *stop = YES; stoppedEarly = YES; // ILLEGAL }}];
    复制代码


      不过如果你在前面加上_block,就会变成可读写了,然后在block执行完后它会保留被赋的值。
      

    1. __block BOOL stoppedEarly = NO;double stopValue = 53.5;[aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { NSLog(@“value for key %@ is %@”, key, value); if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) { *stop = YES; stoppedEarly = YES; // this is legal now }}];if (stoppedEarly) NSLog(@“I stopped logging dictionary values early!”);
    复制代码


      在block里面用了一个实例变量,出来后也是有效的,而且不是只读的。
     

    1.  typedef一个block:
    2.   typedef double (^unary_operation_t)(double op);
    复制代码


      这行代码的意思就是定义一个新类型,它本质上是一个block,它接受一个类型为double的参数,返回值的类型也是double的,新类型的名字叫unary_operation_t。

      已经定义好了这个类型,现在用它声明一个变量,变量名叫square,接下来给它赋值:

    1.   unary_operation_t square;square = ^(double operand) { // the value of the square variable is a block return operand * operand;}
    复制代码


      现在有了一个类型为unary_operation_t的变量square,怎么用呢?就像用一个C语言函数一样:
      

    1. double squareOfFive = square(5.0);
    复制代码


      把5.0作为参数传给block,5.0就是block里面的操作数,它进行平方操作,得到25。

      这有一行代码可以不用typedef直接声明square:
      

    1. double (^square)(double op) = ^(double op) { return op * op; };
    复制代码


      此处的square是一个变量,而不是一个类型。

      一旦定义好unary_operation_t,这种类型实际上是一个block,就可以用它进行函数声明了,把它作为函数的参数,就是声明一个参数为unary_operation_t类型的方法,比如addUnaryOperation:whichExecutesBlock:,第二个参数是block,可以用unary_operation_t来声明这个方法。首先,加入一个property:
     

    1.  @property (nonatomic, strong) NSMutableDictionary *unaryOperations;
    复制代码


      它就是一个用来存储所有unaryOperations的dictionary,用来记录key值的dictionary。

      然后实现addUnaryOperation:whichExecutesBlock:
     

    1.  typedef double (^unary_operation_t)(double op);- (void)addUnaryOperation:(NSString *)op whichExecutesBlock:(unary_operation_t)opBlock { [self.unaryOperations setObject:opBlock forKey:op];}
    复制代码


      这个方法的第二个参数是一个block,unary_operation_t指明了block的类型。把block看成一个对象,通过给定的key加入到dictionary里。block用起来像类一样,实际不是,只是有些相似,不能给它传递消息,可以像安置id一样安置它们。

      ARC负责block的内存管理,由于它本身并不是一个对象,它靠ARC进行内存管理,当block执行完之后,它的内存是自动释放的。

      然后我们就有了一个字典,字典的key是代表操作的字符串,值是block。接着可以这么做:
      

    1. - (double)performOperation:(NSString *)operation{ unary_operation_t unaryOp = [self.unaryOperations objectForKey:operation]; if (unaryOp) { self.operand = unaryOp(self.operand); } . . .}
    复制代码


      大多数不用typedef来声明一个方法,比如
     

    1.  - (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id key, id obj, BOOL *stop))block;
    复制代码


      没有返回值所以是void,注意(^),在括号中间没有其他东西,是因为没有定义type。后面就是block需要的参数,然后就是block。

      block很常见,实际上有简便方法,然后有两件事情需要去做:第一,不必去声明那些能被block里面引用的返回的type,如果它能够在block里被推断出来,比如
     

    1.  NSNumber *secret = [NSNumber numberWithDouble:42.0];[brain addUnaryOperation:@“MoLtUaE” whichExecutesBlock:^(double operand) { return operand * [secret doubleValue];}];
    复制代码


      另外一个就是如果一个block没有参数的话,不必写这个(),比如
     

    1.  [UIView animateWithDuration:5.0 animations:^{ view.opacity = 0.5;}];
    复制代码


      没有参数,没有返回值,仅仅是花括号。

  • 相关阅读:
    [模板] 循环数组的最大子段和
    [最短路][几何][牛客] [国庆集训派对1]-L-New Game
    [洛谷] P1866 编号
    1115 Counting Nodes in a BST (30 分)
    1106 Lowest Price in Supply Chain (25 分)
    1094 The Largest Generation (25 分)
    1090 Highest Price in Supply Chain (25 分)
    树的遍历
    1086 Tree Traversals Again (25 分)
    1079 Total Sales of Supply Chain (25 分 树
  • 原文地址:https://www.cnblogs.com/fakemessi/p/4936317.html
Copyright © 2011-2022 走看看