devios1
devios1

Reputation: 38025

Creating anonymous delegate objects in Objective-C

Cocoa uses delegates extensively to provide (among other things) callback methods for asynchronous operations. However, I personally hate the delegate model and how it pollutes the current class with handlers for very specific child operations. UIAlertView is a perfect example.

Therefore, I'm wondering if it's possible to simply create an anonymous delegate object that meets the requirements of a delegate protocol (such as UIAlertViewDelegate) via blocks and pass this anonymous object wherever a delegate reference is expected.

I imagine something like so:

id myDelegate = @{
    alertView:alertView didDismissWithButtonIndex:index = ^ {
        ...
    }
};

UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:... message:... delegate:myDelegate cancelButtonTitle:... otherButtonTitles:...;
[alertView show];

I've heard Objective-C has some good dynamic language features but I don't know how to simply add a method/selector to an object. Can this be done in a relatively straightforward manner?

Upvotes: 8

Views: 2201

Answers (4)

jszumski
jszumski

Reputation: 7416

You should consider using a category that adds block support to UIAlertView, which seems to address your use case. UIAlertView-Blocks is my favorite one although there are many others.

Upvotes: 2

Chris Devereux
Chris Devereux

Reputation: 5473

Yes, the language features you mention are exposed via the objective-c runtime, although there's no built-in facility to dynamically create delegate classes and the runtime api is not the friendliest of things.

There is a library called A2DynamicDelegate, which does exactly what you're talking about. I haven't used it, but it may be worth investigating.

EDIT: A problem with this approach is that delegates are not retained, so you'll need to either keep a strong reference somewhere else, or an add an associative reference to the UIAlertView. You may find that all this fuss isn't worth it and just adding an extra method to your view controller works better (you can conform to the delegate protocol in a class extension to avoid polluting your interface).

Upvotes: 5

CRD
CRD

Reputation: 53010

One option is to write a class which wraps your blocks for the individual methods of the delegate protocol into a delegate object. For details see this answer.

Upvotes: 3

fumoboy007
fumoboy007

Reputation: 5553

If you want to use blocks with a delegate-based API, you'll have to do some subclassing. For example, see PSAlertView, which subclasses UIAlertView to provide a block-based API.

Upvotes: 0

Related Questions