Objective-C Blocks Quiz


http://blog.parse.com/learn/engineering/objective-c-blocks-quiz/

Do you really know how blocks work in Objective-C? Take this quiz to find out.

All of these examples have been verified with this version of LLVM:

Apple clang version 4.1 (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.4.2
Thread model: posix

Example A

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

This example

  •  
  •  
  •  
  •  
  • Example B

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

    This example

  •  
  •  
  •  
  •  
  • Example C

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

    This example

  •  
  •  
  •  
  •  
  • Example D

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

    This example

  •  
  •  
  •  
  •  
  • Example E

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

    This example

  •  
  •  
  •  
  •  
  • Conclusions

    So, what’s the point of all this? The point is always use ARC. With ARC, blocks pretty much always work correctly. If you’re not using ARC, you better defensively block = [[block copy] autorelease] any time a block outlives the stack frame where it is declared. That will force it to be copied to the heap as an NSMallocBlock.

    Haha! No, of course it’s not that simple. According to Apple:

    Blocks “just work” when you pass blocks up the stack in ARC mode, such as in a return. You don’t have to call Block Copy any more. You still need to use  [^{} copy] when passing “down” the stack into  arrayWithObjects: and other methods that do a retain.

    But one of the LLVM maintainers later said:

    We consider this to be a compiler bug, and it has been fixed for months in the open-source clang repository. What that means for any hypothetical future Xcode release, I cannot say.  :)

    So, hopefully Apple was describing a workaround for bugs that existed at the time their guide was written, and everything should work smoothly with ARC and LLVM in the future. But watch out. 

    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值