I’ve read the online docs about formal and informal protocols on Apple’s documentation site, but I missed the point about informal protocols. I mean,
- a class cannot conform to an informal protocol, it conforms to it by default since informal protocols are almost always categories of the NSObject class.
- If you want to implement an informal protocol, you must redeclare the methods you want to implement in your interface file.
- Another class cannot check if you conform to the informal protocol (the class must check if it responds to some selectors, but the same can be done without the need of an informal protocol).
So, what’s the point of having an informal protocol? I can’t really understand where they could be useful given the three points above and given that you could do the same things without them. I’m sure I’m missing something, maybe you can help.
EDIT: after a while, I still do not see why informal protocols where used, apart from a logical point of view, i.e. group together some methods. Any idea?
You’ve got the grouping together a set of related methods part right. An informal protocol lists which (optional) methods can be implemented if a class needs to ‘conform’ to that informal protocol.
The other reason is the compiler and the target platform ABI. Consider a delegating class whose objects accept a delegate. Internally, methods in the delegating class would do something like:
Without an informal protocol, the compiler would emit warnings for the excerpt above because it wouldn’t be aware that
someMethod:hey:ho:exists, its return type and its parameter types. More importantly, without knowing the method signature, the compiler would have to guess the return type and the argument types in order to prepare the call site, and this guess could very well be a mismatch.For example, looking at the message being sent in the excerpt above the compiler could guess that the method accepts an integer, an NSString, and another NSString as arguments. But what if the method is originally supposed to accept a floating point number as the first argument? Passing an integer argument (in this case, the argument is stored in a standard register) is different from passing a 64-bit floating point argument (in this case, a SSE register). And what if the method actually supports variable arguments in the last argument instead of a single string? The compiler wouldn’t prepare the call site accordingly, which would lead to crashes.
Generating the assembly of the excerpt above helps illustrate this problem:
As you can see, 42 was stored in register EDX.
However, if we add an informal protocol stating that the first parameter is of type
float:then the compiler prepares the call site differently:
As you can see, 42 was stored in register XMM0.
And if we change the informal protocol so that the last argument is variadic:
then the compiler prepares the call site in another manner:
Note the
movb $0, %alinstruction. That’s required by the x86_64 ABI: when calling a variadic function, the caller must store in AL the number of floating-point registers that have been used. In this case, none, hence$0.In summary, informal protocols, besides grouping related methods, help the compiler identify the signature of a method and correctly prepare the call site before sending a message. However, given that Objective-C now supports optional methods in a formal protocol declaration, informal protocols aren’t needed any longer.