Objective-C: Blocks vs. Selectors vs. Protocols
I would just go with your first approach. It's a tried and true pattern in Cocoa, and seems to fit very well into what you're doing.
A few comments on the other approaches:
- Informal protocol - I don't really see any advantage of doing this over a formal protocol. Every since formal protocols gained
@optional
methods, the utility of informal protocols is much less. - Passing SELs - I don't think this is an established pattern in Cocoa. I personally wouldn't consider it as better than the delegate approach, but if it fits your thinking better, then go for it. You're not really getting rid of state; you're just transforming into something else. Personally, I'd prefer to have an ivar that I can set and check without having to use selector types.
- Passing blocks - This is sort of a new-age approach, and it has some merit. I think you need to be careful though because, in my opinion, it doesn't scale really well. For example, if NSTableView's delegate and data source methods were all blocks, I would personally find that somewhat annoying. Imagine if you wanted to set 10 different blocks, your
-awakeFromNib
(or whatever) method would be pretty big. Individual methods seem more appropriate in this case. However, if you're sure that you're never going to go beyond, say, two methods, then the block approach seems more reasonable.
The 'traditional' way to do this is with a protocol. Informal ones were used before @protocol was added to the language, but that was before my time and for at least the last few years informal protocols have been discouraged, especially given the @optional specifier. As for a 'delegate' which passes two SELs, this just seems more ugly than declaring a formal protocol, and generally doesn't seem right to me. Blocks are very new (esp. on iOS), as these things go, and while we have yet to see the tremendous volume of documentation/blogs on the best tried and true style, I like the idea, and this seems to be one of the things blocks are best for: neat new control flow structures.
Basically what I'm trying to say is that each of these methods vary in age, with none being better than the last except for style, which obviously counts for an awful lot, and is ultimately why each of these things was created. Basically, go with the newest thing you feel comfortable with, which should be either blocks or a formal protocol, and that your confusion is most likely coming from reading conflicting sources because they were written at different times, but with time in perspective, it is clear to see which supersedes the others.
[Controller askForSelection:^(id selection){
//blah blah blah
} canceled:^{
//blah blah blah
}];
is probably a hell of a lot more concise than defining two extra methods, and a protocol for them (formally or otherwise) or passing the SELs and storing them in ivars, etc.