Tomer Shiri came up with a fascinating way to do generics in Objective
C. Just drop a single .h
file in your project, then declare your
objects like so:
GENERICSABLE(SearchResult)
@interface SearchResult : NSObject<SearchResult>
@property (nonatomic, strong) NSString* description;
// ...
@end
That GENERICSABLE(...)
preprocessor macro does some crazy magic to define
categories on all the built in Foundation collection classes (NSArray
,
NSSet
, etc.). Now, you can declare a collection for your objects like so:
SearchResult *found = [[SearchResult alloc] init];
NSMutableArray<SearchResult> *results = [NSMutableArray array];
[results addObject:found];
NSString *aString = results[0]; // Gives a warning
That last line shows a warning because the results
array is expecting to
return a SearchResult
object and not an NSString
. (Cue all the Java and C#
developers and their chuckling at us for discovering something so…novel.)
It’s not completely airtight since you can still add any object to the
collection without a warning, but getting objects out and creating new
collections based on other collections are protected as you’d expect.
The real kicker, however, is that these categories are just the interfaces. There’s not a bit of implementation code linked in to make it work. It’s purely a preprocessed compile time trick.
The usual disclaimer: Be careful. I’ve built a successful career cultivating my fear of the C preprocessor. Still, I can’t help but smile at the technique.
✦ PermalinkMy books...