Can an ObjC class object conform to a protocol?

2019-03-12 17:08发布

问题:

Is there a way to indicate to the compiler that a class object conforms to a protocol?

As I understand, by creating +(void)foo class methods, an instance of that class object will have those methods as instance methods. So, as long as I create +(void)foo methods for all required protocol methods, I can have a class object act as a delegate.

My problem of course is that in the class's header file, I only know how to indicate that instances of the class conform to the protocol (as is typically the case). So, the best I've figured out is to cast the class object like so:

something.delegate = (id<SomethingDelegate>)[self class]

Any ideas?

Related, but different: ObjC: is there such a thing as a "class protocol"?

回答1:

What you're doing now is correct as it will silence warnings which is your goal. You will be sending the class object messages defined in the protocol for instances which is a bit confusing, but the runtime doesn't care.

Think about it this way: you want to set a delegate to an object that responds to the messages defined in the protocol. Your class does this, and your class is also an object. Therefore, you should treat your class like an object that conforms to that protocol. Therefore, what you've written is completely correct (based on what you're trying to do).

One thing to note, though, is this class will not properly respond to conformsToProtocol:. This is generally okay for a delegate setup anyway (delegates don't usually check if the class conforms — they just check if it can respond to a selector).

As a side note, one thing you can do syntactically is:

Class<SomethingDelegate> variable = (Class<SomethingDelegate>)[self class];

The difference here is that the compiler will use the class methods from the protocol instead of instance messages. This is not what you want in your case, though.



回答2:

There is no Objective-C syntax to indicate that a metaclass conforms to a protocol.

I think you can do it at runtime, by using class_addProtocol on the metaclass. But I haven't tried it.

I guess you could also write a +conformsToProtocol: method on your class, and lie about your conformance. This could have unexpected side-effects, since there's already a +conformsToProtocol: on NSObject (in addition to -conformsToProtocol:).

Neither of these will eliminate the need for a cast to shut the compiler up. Just use a singleton.