What is the point of Protocols?

2019-01-26 19:49发布

I've been writing various stuff using protocols as per example code, but also using some third party stuff, and they seem to adopt quite different approaches. Some specifically adopt the protocols in the interface using

@interface myClass <myProtocol>

others don't do that at all and merely pass themselves and are then set as delegates, but the end result seems to be exactly the same. I've tried both, and they both work fine. If someone was able to explain this I'd be a happy camper! Thanks very much.

3条回答
唯我独甜
2楼-- · 2019-01-26 20:29

Objective-C can do both static and dynamic typing, so that protocols aren’t really required for the usual use cases. You can always type your delegate as id and then send it whatever messages you want. (The compiler will warn you if you attempt to send a message that’s not visible from the current file. That’s about the only sanity check it can do for id-typed objects without doing advanced type inference.)

But narrowing the id type down with protocols is nice and recommended, because 1) the code is more readable, 2) the compiler will warn you if you try to send the delegate some bogus message and 3) you’ll get better code completion.

查看更多
啃猪蹄的小仙女
3楼-- · 2019-01-26 20:44

Also the Xcode Code Sense can be very helpful if you use protocols. Sometimes it will suggest the missing methods.

查看更多
叛逆
4楼-- · 2019-01-26 20:49

A protocol declares a set of messages that an object must respond to (or with @optional, can respond to). In Objective-C, its only point (almost)* is to allow the compiler to flag up warnings if you pass an object that doesn't implement all the methods of the protocol with the correct signatures.

Taking a simple example: NSMutalbeDictionary has a method -setObject:ForKey: which sets the value for a particular key. The key is declared as type id which means you can pass any object and the compiler will not complain. However, the documentation for the method says:

The key is copied (using copyWithZone:; keys must conform to the NSCopying protocol).

so if you pass an object that doesn't have a -copyWithZone: method, you will get a exception at run time saying the key does not respond to -copyWithZone:. It would have been nice if the compiler could have detected your error.

If Apple had declared the method

-(void)setObject:(id)anObject forKey:(id<NSCopying>)aKey;

the compiler would have known about the requirement for -copyWithZone: (it's the only method declared in NSCopying) and would have caught any instances of passing incompatible objects at compile time. I think the reason they didn't do that is for backward compatibility. If bbum is reading, he might know the real reason why not.


*I say "almost" because you can test to see if an object conforms to a protocol at run time.

查看更多
登录 后发表回答