<<Effective Objective-C 2.0 编写高质量iOS与OS X代码的52个有效方法>>笔记-块与大中枢派发...

37、理解“块”这一概念

  “块”是一种可在C、C++ 及 Objective-C 代码中使用的“词法闭包”,它极为有用,这主要是因为借由此机制,开发者可将代码像对象一样传递,令其在不同环境下运行。还有个关键的地方是,在定义“快”的范围内,它可以访问到中的全部变量。

  下面是一个最简单的块:

  ^{

    //Block implementation here

  }

  块其实就是个值,而且自有其相关类型。与 int、float 或 Objective-C 对象一样,也可以把块赋给变量,然后像使用其他变量那样使用它。块类型的语法与函数指针近似。

  默认情况下,为块所捕获的变量,是不可以在块里修改的。声明变量的时候可以加上 __block 修饰符,这样就可以在块内修改了。

  如果将块定义在 Objective-C 类的实例方法中,可以访问类的所以实例变量和self变量。块总能修改实例变量,所以在声明时无须加 __block。

  self 也是个对象,因而块在捕获它时也会将其保留,如果 self 所指代的那个对象同时也保留了块,那么这种情况通常会导致“保留环”。

  定义块的时候,其所占的内存区域是分配在栈中的,这就是说,块只在定义它的范围内有效,例如,下面这段代码就有危险:

  void (^block)();

  if (/* some condition */ ) {

    block = ^{

      NSLog(@"Block A");

    };

  } else {

    block = ^{

      NSLog(@"Block A");

    };

  }

  block();

  定义在if及else语句中的两个块都分配在栈内存中.编译器会给每个块分配好栈内存,然而等离开了相应的范围之后,编译器有可能把分配给块的内存覆写掉,于是,这两个块只能保证在对应的if或else语句范围内有效.这样写出来的代码可以编译,但运行起来时而正确,时而错误.

  为解决此问题,可给块对象发送copy消息以拷贝之.这样的话,就可以把块从栈复制到堆了.拷贝后的块,可以在定义它的那个范围之外使用.

  明白这点后,我们只需给代码加上两个copy方法调用,就可以令其变的安全了:

  void (^block)();

  if (/* some condition */ ) {

    block = [^{

      NSLog(@"Block A");

    } copy];

  } else {

    block = [^{

      NSLog(@"Block A");

    } copy];

  }

  block();

38、为常用的块类型创建 typedef

  以 typedef 重新定义块类型,可令块变量用起来更加简单.

  定义新类型时应遵从现有的命名习惯,勿使其名称与别的类型相冲突.

  不妨为同一个块签名定义多个类型别名.如果要重构的代码使用了块类型的某个别名,那么只需修改相应 typedef 中的块签名即可,无需改动其他 typedef.

39、用 handler 块降低代码分散程度

  在创建对象时,可以使用内联的 handler 块将相关业务逻辑一并声明.

  在有多个实例需要监控时,如果采用委托模式,那么经常需要根据传入的对象来切换,而若改用 handler 块来实现,则可直接将块与相关对象放在一起.

  设计 API 时如果用到了 handler 块,那么可以增加一个参数,使调用者可以通过此参数来决定应该把块安排在哪个队列上执行.

40、用块引用其所属对象时不要出现保留环

  如果块所捕获的对象直接或间接地保留了块本身,那么就得担心保留环问题.

  一定要找个适当的时机解除保留环,而不能把责任推给 API 的调用者.

 

转载于:https://www.cnblogs.com/670074760-zsx/p/7283821.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值