views:

357

answers:

3

I'm new to Objective-C and development on Apple's platforms, but hopefully I can frame this question in an understandable way regardless :)

I want to parse an XML feed for my iPhone app, and I decided instead of shoving all of the delegation methods from an instance of NSXMLParser into my view controller, I'd wrap this up inside of a FeedParser class. After reading a few docs and example code, here's what I came up with:

@protocol FeedParserDelegate <NSObject>

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end


@interface FeedParser : NSObject {
    id <FeedParserDelegate> delegate;
}

@property (nonatomic, assign) id <FeedParserDelegate> delegate;

- (id)initWithURL:(NSURL *)url delegate:(id<FeedParserDelegate>)theDelegate;

@end

Simple. Delegates of my FeedParser object just have to implement parserDidLoadEpisodes.

However, as I started actually making my FeedParser class use NSXMLParser, I realized that I didn't have to specify that FeedParser implements a protocol for NSXMLParser -- I could just implement the delegate methods that I wanted to do something with. I think I've noticed this with other classes that follow the delegate pattern, too, but not all.

So why wouldn't I too just not bother with specifying a formal protocol for my FeedParser class? It would cut away some perhaps unnecessary code. I guess the question is: why would I want to create a formal protocol instead of just doing something like just checking to see if the method is implemented on the delegate with respondsToSelector? Is it only so that the compiler will issue nice warnings if a required delegate method isn't implemented?

+2  A: 

Always, always, always favor compile-time error checking over run-time. You could of course ask the class if it supports the method, but why ask when you can know?

The answer is no, you don't have to. But you should want to. :)

Nick Veys
+2  A: 

Adding a protocol makes the compiler check things for you. If you don't get those nice errors at compile time, then you'll get them later at run time when they're harder to track down.

GoatRider
+5  A: 

A protocol declared with @protocol is called a "formal protocol". The other way to do it is to declare a category (a set of additional methods) on NSObject, like so:

@interface NSObject (FeedParserDelegate)

- (void)parserDidLoadEpisodes:(NSArray *)episodes;

@end

Then simply define that method for any object that you want to be a feed parser delegate, and leave it undefined otherwise. This is called an "informal protocol".

Why are there two ways? Well, here's a hint: the informal protocols came first. What it comes down to is that they added formal protocols because informal ones weren't cutting it. Informal protocols make it too easy to forget an important method or try to use an object as a delegate for something it's not designed to work with.

Basically, for the cost of adding <FeedParserDelegate> here and there, you can get the compiler to do your debugging for you. The compiler will generate warnings for the most common delegate bugs, which saves you time if you make one of those mistakes. Why not take advantage of its helpfulness?

Brent Royal-Gordon
Great answer. I did what I should have done before and actually looked at the header file for NSXMLParser, and indeed, an *informal* protocol is exactly what NSXMLParser defines under the hood. Thanks for clearing it up!
Brent Dillingham