zoukankan      html  css  js  c++  java
  • Block小测试

    几个blcok小测试,看看你对block掌握如何

    例子1

    void exampleA() {
      char a = 'A';
      ^{
        printf("%c
    ", a);
      }();
    }
    

    这个例子:

    A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行
    C.不使用ARC才能正常运行   D.永远无法正常运行


    例子2:

    void exampleB_addBlockToArray(NSMutableArray *array) {
      char b = 'B';
      [array addObject:^{
        printf("%c
    ", b);
      }];
    }
     
    void exampleB() {
      NSMutableArray *array = [NSMutableArray array];
      exampleB_addBlockToArray(array);
      void (^block)() = [array objectAtIndex:0];
      block();
    }
    
    



    A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行
    C.不使用ARC才能正常运行   D.永远无法正常运行



    例子3

    void exampleC_addBlockToArray(NSMutableArray *array) {
      [array addObject:^{
        printf("C
    ");
      }];
    }
     
    void exampleC() {
      NSMutableArray *array = [NSMutableArray array];
      exampleC_addBlockToArray(array);
      void (^block)() = [array objectAtIndex:0];
      block();
    }
    
    



    A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行
    C.不使用ARC才能正常运行   D.永远无法正常运行


    例子4

    typedef void (^dBlock)();
     
    dBlock exampleD_getBlock() {
      char d = 'D';
      return ^{
        printf("%c
    ", d);
      };
    }
     
    void exampleD() {
      exampleD_getBlock()();
    }
    
    



    A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行
    C.不使用ARC才能正常运行   D.永远无法正常运行



    例子5

    typedef void (^eBlock)();
     
    eBlock exampleE_getBlock() {
      char e = 'E';
      void (^block)() = ^{
        printf("%c
    ", e);
      };
      return block;
    }
     
    void exampleE() {
      eBlock block = exampleE_getBlock();
      block();
    }
    
    




    A.始终能够正常运行                B.只有在使用ARC的情况下才能正常运行
    C.不使用ARC才能正常运行   D.永远无法正常运行

    答案
    例子1

    A正确。这个例子可以正常运行。储存exampleA的栈只有在block停止执行之后才会释放,因此,无论此Block由系统分配到栈中还是我们自己手动分配到堆中,它都可以正常执行。


    例子2

    B正确。如果不使用ARC,这个block是一个NSStackBlock,分配给exampleB_addBlockToArray的栈上。而当它在exampleB中执行的时候,由于栈被清空,block不再有效。

    而使用ARC的话,block会分配到堆中,作为一个自动释放的NSMallocBlock


    例子3

    A正确

    由于block在自己的环路中不会抓取任何变量,它不需要在在运行的时候设置state,它会作为一个NSGlobalBlock编译。它既不是栈也不是堆,而是代码片段的一部分。所以它始终都能正常运行。


    例子4

    B正确。这个例子和例子2类似。如果不使用ARC,block会在exampleD_getBlock的栈上创建起来。然后当功能返回的时候会立即失效。

    然而,以这个例子来说,这个错误非常明显,所以编译器进行编译会失败,错误提示是:error: returning block that lives on the local stack(错误,返回的block位于本地的栈)。


    例子5

    B正确。这个例子和例子4类似,除了编译器没有认出有错误,所以代码会进行编译然后崩溃。更糟糕的是,这个例子比较特别,如果你关闭了优化,则可以正常运行。所以在测试的时候需要注意。

    而如果使用ARC的话,block则会正确的位于堆上,作为一个自动释放的NSMAllocBlock。


    结论
    这套小测试有什么意义呢?意义就是要一直使用ARC。使用ARC,block大部分情况下都可以正常运行。
    如果不使用ARC,谨慎起见,可以block = [[block copy] autorelease],这样block会比申明它的栈flame的有效期长。这样block会被作为一个NSMAllocBlock强制复制到堆上。
    但是,当然不会这么简单,根据苹果的文档,
    Block只有当你在ARC模式下传递block到栈上才会工作,比如说返回的时候。你不需要再次调用Block Copy了。但是当block从栈上传递到 arrayWithObjects: 和其他做了一个retain的方法是时,仍然需要使用[^{} copy]。
    但是有一个LLVM的维护者之后也说过:
    我们认为这是编译器的bug,它现在已经修复了。但是Xcode以后是否会在以后发布的新版本中解决这个问题,我也不知道。
    所以,希望,苹果也把它认为是一个bug,在以后的新版本中会解决这个问题。让我们看看会怎么样吧。

    原文:http://blog.parse.com/2013/02/05/objective-c-blocks-quiz/      

  • 相关阅读:
    BZOJ2956: 模积和——整除分块
    BZOJ1257: [CQOI2007]余数之和——整除分块
    数位DP【模板】
    2019HDU多校第7场——构造
    AtCoder Grand Contest 032 B
    P3599 Koishi Loves Construction——构造题
    CF C. Vladik and fractions——构造题
    RMQ问题【模板】
    libevent多线程使用事项
    Linux查看进程运行的完整路径方法
  • 原文地址:https://www.cnblogs.com/menchao/p/4877348.html
Copyright © 2011-2022 走看看