Objective-C runtime: What does declaring a variable of type Class (objc_class) conforming to a protocol mean?
objective-c, objective-c-runtime
Solution
According to Apple's documentation:
Protocols can’t be used to type class objects. Only instances can be statically typed to a protocol, just as only instances can be statically typed to a class. (However, at runtime, both classes and instances respond to a conformsToProtocol: message.)
This is from old documentation, but there's nothing saying that it has since changed. But assuming it's still valid, based on that, you shouldn't be doing what you're doing. Instances of `NSString` may conform to that protocol, but you shouldn't be saying that the `NSString` `Class` object conforms to it.
As for why it gives you the error, I believe it's because when you're specifying the protocol, it will report an error for methods not in that protocol. For example, the following gives an error:
Class<NSSecureCoding> bah = [NSString class];
id object = [bah class];
But the following will compile (although it gives a warning that `class` is an instance method, not a class method):
Class<NSObject> bah = [NSString class];
id object = [bah class];
Also you'll notice that `new` is not defined in the `NSObject` protocol, only in the `NSObject` class.
So when you just specify `Class`, the compiler appears to do something similar to when you specify `id` in that it doesn't know the exact type, so it will let you call methods from any known type. But when you add the protocol to it, it will only let you call methods from that protocol.
If you want to ensure that whatever you assign to `bah` conforms to a particular protocol while just using `Class`, you could use the following:
if ([bah conformsToProtocol:@protocol(NSSecureCoding)])
Problem
``` Class bah = [NSString class]; id object = [bah new]; ``` Compiles with absolutely no issues. ``` Class<NSSecureCoding> bah = [NSString class]; id object = [bah new]; ``` Returns the error "No known class method for selector 'new'". Why does the first instance understand that it can call the `+new` method defined on NSObject but the second instance does not?