Delegate VS Block in API Design

When asked in which cases delegate or block is preferable for API design, I didn't have enough time to think thoroughly so I just gave the answer off the top of my head: "Wherever delegate works block also works."

I knew it was not a good answer so I kept thinking of it. Now I have a more clear choice and systematic reasoning for my choice for these two cases respectively.

  1. One-Off Callbacks

    Example: [NSArray enumerateObjectsUsingBlock:].

    Block is much more convenient. The caller of block is responsible to release it after finishing using it. It means even if there is strong reference cycle between block supplier and block, the cycle is temporary hence coder does not need to write more complex code using weak reference in block to avoid the cycle.

  2. Lifetime Callbacks

    Example: UITableViewDataSource & UITableViewDelegate.

    Delegate is more user-friendly. The problem with block here is that reference cycle is so common and no one can break the cycle for you. API users are forced to write more clumsy code to avoid the cycle at the first place or to break it at the end. Though every competent coder should be able to handle this situation, as an API designer I should not require that from my users. I should make them think as little as possible and give them as few as possible opportunities to misuse my API.

    Beside being less error prone, there is another reason for choosing delegate over block. The number of lifetime callbacks is usually not small. It is cleaner to organize these callbacks as the API of a delegate and make a single delegate assignment than to make a lot of block assignments.

Though it is true that "wherever delegate works block also works", sometimes delegate is still a better choice in API design.