iOS开发中，block与代理的对比，双方的优缺点及在什么样的环境下，优先使用哪一种更为合适？
block 和 delegate 都可以通知外面。block 更轻型，使用更简单，能够直接访问上下文，这样类中不需要存储临时数据，使用 block的代码通常会在同一个地方，这样读代码也连贯。delegate更重一些，需要实现接口，它的方法分离开来，很多时候需要存储一些临时数据，另外相关的代码会被分离到各处，没有 block 好读。

应该优先使用 block。而有两个情况可以考虑 delegate。

1. 有多个相关方法。假如每个方法都设置一个 block, 这样会更麻烦。而 delegate 让多个方法分成一组，只需要设置一次，就可以多次回调。当多于3 个方法时就应该优先采用 delegate。

比如一个网络类，假如只有成功和失败两种情况，每个方法可以设计成单独 block。但假如存在多个方法，比如有成功、失败、缓存、https验证，网络进度等等，这种情况下，delegate 就要比 block 要好。

在 swift 中，利用 enum, 多个方法也可以合并成一个 block 接口。swift 中的枚举根据情况不同，可以关联不同数据类型。而在 objc就不建议这样做，objc 这种情况下，额外数据需要使用 NSObject 或者 字典进行强转，接口就不够安全。

2. 为了避免循环引用，也可以使用 delegate。使用 block时稍微不注意就形成循环引用，导致对象释放不了。这种循环引用，一旦出现就比较难检查出来。而 delegate的方法是分离开的，并不会引用上下文，因此会更安全些。

假如写一个库供他人使用，不清楚使用者的水平如何。这时为防止误用，宁愿麻烦一些，笨一些，使用 delegate 来替代 block。

将 block 简单分类，有三种情形。

* 临时性的，只用在栈当中，不会存储起来。

比如数组的 foreach 遍历，这个遍历用到的 block 是临时的，不会存储起来。

* 需要存储起来，但只会调用一次，或者有一个完成时期。

比如一个 UIView 的动画，动画完成之后，需要使用 block 通知外面，一旦调用 block 之后，这个 block 就可以删掉。

* 需要存储起来，可能会调用多次。

比如按钮的点击事件，假如采用 block 实现，这种 block 就需要长期存储，并且会调用多次。调用之后，block也不可以删除，可能还有下一次按钮的点击。

对于临时性的，只在栈中使用的 block, 没有循环引用问题，block 会自动释放。而只调用一次的 block，需要看内部的实现，正确的实现应该是block 调用之后，马上赋值为空，这样 block 也会释放，同样不会循环引用。

而多次调用时，block 需要长期存储，就很容易出现循环引用问题。

Cocoa 中的 API 设计也是这样的，临时性的，只会调用一次的，采用 block。而多次调用的，并不会使用 block。比如按钮事件，就使用target-action。有些库将按钮事件从 target-action 封装成 block 接口, 反而容易出问题。