Hi there, I think I understood the difference between (formal) Protocols and Categories. Now, if I got it right, informal protocols should be categories (usually defined on NSObject) which are used for certain purposes (maybe to give the chance to implement only a part of the methods listed in it, unlike formal protocols). I need to be sure about it: could anyone confirm that an Informal Protocol just IS a Category (or explain the differences)? Thank you.
The Objective-C Manual says you are right - informal protocols are typically categories.
In addition to formal protocols, you can also define an informal protocol by grouping the methods in a category declaration:
However, you can implement an informal protocol just by agreeing to it by word of mouth - certainly I've never been tempted to look for a category when implementing delegate methods for interface builder; and Categories are used for other things besides informal protocols, too.
Category is an extension for class functionality - this is an implementation of some methods:
@interface NSObject (MyCategory)
- (void)doSomething;
@end
...
@implementation NSObject (MyCategory)
- (void)doSomething {
// do something...
}
@end
Formal protocol is something completely different. If you are familiar with some other object oriented language then it is like interface (in Java, C++, C# etc.).
Protocol may be attached to any class implementation like this:
@protocol MyProtocol
@required
- (void)doSomething;
@optional
- (void)doSomethingOptional;
@end
...
@interface MyClass : NSObject <MyProtocol> {
}
@end
...
@implementation MyClass
- (void)doSomething {
// do something...
}
@end
According to the documentation, the informal protocols ARE categories of NSObject class (I've never used this approach):
@interface NSObject (MyInformalProtocol)
- (void)doSomething;
@end
...
@implementation NSObject (MyInformalProtocol)
- (void)doSomething {
// do something...
}
@end
Informal protocols are indeed simply categories defined on NSObject, but if you're defining a delegate interface, there's a better way. Instead, use formal protocols (i.e. real, actual @protocol definitions) with optional methods. That allows you to test for the type of the delegate (i.e. that it actually conforms to the protocol) at compile-time, and get a warning if you use the wrong object.
@protocol GLFunkyObjectDelegate
@optional
-(void)funkyObject: (GLFunkyObject *)obj willDoSomething: (GLSomeThing *)thing;
-(void)funkyObject: (GLFunkyObject *)obj didDoSomething: (GLSomeThing *)thing;
@end
@interface GLFunkyObject {
id <GLFunkyObjectDelegate> delegate;
}
//...
@end
A protocol is a definition of an interface ONLY.
A category (against NSObject) is both a definition of an interface, and an implementation of that interface that all subclasses (of NSObject) will inherit, unless they override the category's methods.
Whilst Apple has chosen, in the past, to define informal protocols by creating categories against NSObject does not mean that one is the definition of the other.
The fact that you can half-define a category, by declaring the interface but not actually implementing it, should (in a just and fair world) cause compilation errors to occur since the Objective-C compiler definitely complains about 'incomplete implementation' for real interfaces. But they've been abused for long enough that you can expect the behaviour won't change.