Last active
November 25, 2016 14:53
-
-
Save douglashill/802ed825389cc5de6e9d to your computer and use it in GitHub Desktop.
A quick look at variance with Objective-C generics. `NSSet` is covariant on its `ObjectType`, while `NSHashTable` is invariant. Contravariance is also supported.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import Foundation; | |
@interface ContravariantCollection<__contravariant ObjectType> : NSObject | |
@end | |
@implementation ContravariantCollection | |
@end | |
void stringSetThing(NSSet<NSString *> *set) { | |
} | |
void mutableStringSetThing(NSSet<NSMutableString *> *set) { | |
} | |
void stringHashTableThing(NSHashTable<NSString *> *hashTable) { | |
} | |
void mutableStringHashTableThing(NSHashTable<NSMutableString *> *hashTable) { | |
} | |
void stringContraThing(ContravariantCollection<NSString *> *set) { | |
} | |
void mutableStringContraThing(ContravariantCollection<NSMutableString *> *set) { | |
} | |
int main(int argc, char *argv[]) { | |
@autoreleasepool { | |
NSSet<NSString *> *setOfStrings; | |
NSSet<NSMutableString *> *setOfMutableStrings; | |
stringSetThing(setOfStrings); | |
stringSetThing(setOfMutableStrings); // Okay, because NSSet<NSMutableString *> is a subtype of NSSet<NSString *> | |
mutableStringSetThing(setOfStrings); // Warning: Incompatible pointer types passing 'NSSet<NSString *> *' to parameter of type 'NSSet<NSMutableString *> *' | |
mutableStringSetThing(setOfMutableStrings); | |
NSHashTable<NSString *> *tableOfStrings; | |
NSHashTable<NSMutableString *> *tableOfMutableStrings; | |
stringHashTableThing(tableOfStrings); | |
stringHashTableThing(tableOfMutableStrings); // Warning: Incompatible pointer types passing 'NSHashTable<NSMutableString *> *' to parameter of type 'NSHashTable<NSString *> *' | |
mutableStringHashTableThing(tableOfStrings); // Warning: Incompatible pointer types passing 'NSHashTable<NSString *> *' to parameter of type 'NSHashTable<NSMutableString *> *' | |
mutableStringHashTableThing(tableOfMutableStrings); | |
ContravariantCollection<NSString *> *collectionOfStrings; | |
ContravariantCollection<NSMutableString *> *collectionOfMutableStrings; | |
stringContraThing(collectionOfStrings); | |
stringContraThing(collectionOfMutableStrings); // Warning: Incompatible pointer types passing 'ContravariantCollection<NSMutableString *> *' to parameter of type 'ContravariantCollection<NSString *> *' | |
mutableStringContraThing(collectionOfStrings); // Okay, because MyCollection<NSString *> is a subtype of MyCollection<NSMutableString *> | |
mutableStringContraThing(collectionOfMutableStrings); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bob’s comment about variance on this Objective C Generics article clearly explains why Apple’s immutable collections are covariant, and their mutable collections are invariant.