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?
The Objective-C runtime is a runtime library that provides support for the dynamic properties of the Objective-C language, and as such is linked to by all Objective-C apps. Objective-C runtime library support functions are implemented in the shared library found at /usr/lib/libobjc.
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)])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With