Reputation: 23
Im trying to understand the high level implementation of protocols without delegates in Apple frameworks. When a subClass conforms to and implements a protocol method, how is that method called? Lets consider the NSCoder protocol methods (encodeWithCoder: and initWithCoder:) for instance.
Without delegates, could you provide any uses cases for protocols (other than achieving polymorphism? I see that some methods could be abstracted away from base classes and grouped into an interfaces but without any implementation (as mixins for instance), what is the significant use?
Upvotes: 0
Views: 125
Reputation: 1099
Taking the example of the NSCoding Protocol, the two required methods in the protocol, basically implement the steps an object should perform to encode itself to be archived. It also implements the initWithCoder to recreate the object from the archive.
Lets say you create a custom object, only your object knows which properties it needs to archive.
When you call a method to archive your custom object, the method call ultimately flow to your encodeWithCoder or initWithCoder to take action specific to your class.
***** Updated ****
Looking at this with an example : Lets say our data structure looks like this
someArray = [String,CustomObject,aDictionary]
When we want to archive someArray, we call the archiveRootObject method on it. Now inorder for someArray to archive itself, it needs all its contained items to inturn archive themselves. The Array simply instructs the sub items to archiver themselves calling the encodeWithCoder method on them.
By adopting and conforming to the NSCoding protocol, you are just confirming to the root array that Yes, I know how to archive and unarchive myself.
Hope this helps.
Upvotes: 0
Reputation: 4805
First, protocol methods are not special in any way. They, like every other Objective-C method, gets called by a message sent to an object. There's nothing special about that part of things. Protocols are basically just a hint to the compiler, though you can query whether an object conforms to one at runtime and make decisions based on that.
You can verify this by implementing a protocol method (or the entire protocol) without declaring that fact in a classes' interface, and call the function on an instance of that object after casting it to be id<YourProtocol>
, and it will work.
You can (and sometimes should) call NSCoding
methods yourself -- you may decide that you want to persist objects to the disk, and that this is the best way to do it.
NSCoding
is actually a great example of why protocols are still useful even though they do not provide any implementation -- the implementation of initWithCoder:
and encodeWithCoder:
will be different for every class that implements them -- there is no sense in providing an implementation.
Building on that, consider the datasource
property of a UICollectionView
; as there is no multiple inheritance in Objective-C, it would be undesirable for the datasource to be a class itself, as that would prevent you from using a UIViewController
as the data source, and force you to make a whole new class for that express purpose.
Protocols can also be used to implement multiple inheritance in a type safe way without redeclaring the interface of the giver in the inheritor. If the entire interface of the class being inherited from is a protocol, then the inheritor can simply conform to that protocol as well.
Objective-C does provide mixins in the form of Categories, which can implement protocols on existing classes.
For a full throated defense of protocols (in Swift), see the Protocol-Oriented Programming WWWDC 2015 talk.
Upvotes: 3