What does a variable defined as `Class<SomeProtocol> myClass` mean?

269 views Asked by At

I am used to seeing things like id<NSCopying> myVar or MyObject<NSCopying> myVar, where we are stating that the variable in question can happily have NSCopying methods called on it without the compiler throwing a wobbly.

But I recently spotted some code that defined a variable like this:

Class<NSCopying> myClass;

I was wondering what this actually means as it seems subtly different from the top two examples. It seems like we're saying that the variable myClass can happily accept method calls from NSCopying - but having a class type able to accept these instance variable methods doesn't seem to make much sense.

It has occurred to me that variables of type class are technically objects themselves which is probably confusing me or the compiler (probably me!).

So I guess I'm asking:

  1. What does something like Class<NSCopying> myClass; actually mean
  2. How does Class<NSCopying> myClass; differ to something like id<NSCopying> myVar
  3. Where could something like Class<NSCopying> myClass; be meaningfully used?

Notes:

  • I am just using NSCopying as an example and isn't integral to my use case
  • Wherever I refer to Class I mean the Obj-C keyword Class for declaring variables that are of type Class. I am not using this as a generic term for any class type.
3

There are 3 answers

1
Roman On

Well I think it might mean that Class <NSCopying> myClass points to a class that implements NSCopying protocol. It can be useful if protocol has class method declarations and you want to call them.

For example:

    @protocol NSSecureCoding <NSCoding>
       @required
       // The Secure Coding Guide should be consulted when writing methods that decode data.
       + (BOOL)supportsSecureCoding;
    @end
1
Nikolai Ruhe On

Class<ProtocolName> is the type of a variable pointing to a class object with a meta class that conforms to ProtocolName. In other words: The class implements the methods from ProtocolName with class methods.

Example: NSCopying contains one required method:

@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end

Class<NSCopying> means that there is a method

+ (id)copyWithZone:(NSZone *)zone;

in the class being pointed to. That is true for all NSObject derived classes and useful for using class objects as dictionary keys. See the documentation.

3
Wain On
id <NSCopying> myVar

Using id you can supply an instance of any type of class (so long as it implements the protocol, or you cast it to make the compiler trust you).

Class <NSCopying> myClass

Using Class means you can only supply a Class, not an instance.

Say you wanted your app to be configurable. Say you had a number of classes which offered a number of different features, but you didn't care about inheritance they had, just how to create and configure them. You could use a protocol that the class has to conform to and offer a method where the classes can be registered. Then you can instantiate those classes using the defined protocol without knowing anything else about the class.