Objective-C: Generics

Re-watching the WWDC 2015, you probably noticed that it was all about Swift. That’s a given, with the release of Swift 2.0 back then, Apple announced a lot of additions to the Swift programming language such as protocol extensions, new error handling API and some additional syntax to name a few. That’s not the end of it, Apple also announced Objective-C Generics albeit ‘lightweight’. Since Xcode 7, generics became available to Objective-C. The biggest benefit of this feature is a better interoperability between Objective-C and Swift.

Why we want Generics?

Often times, we want to write a class that works against arbitrary type without actually knowing what that type is. We might find out when we go to use that class elsewhere in our code, or we might want to use it with range of types and therefore cannot make it type specific. But then again, there are times that we use this class and we want to make sure that it will only accept a specific type. A good example of such class is Apple’s NSArray.

The basics

Let’s start with an example. Before the introduction of generics, we declared mutable arrays as follows:
NSMutableArray *stringArray = [[NSMutableArray alloc] init];
[stringArray addObject:@"First String"];
[stringArray addObject:@"Second String"];
Now you have the possibility to declare a type for the array’s objects:
NSMutableArray *stringArray = [[NSMutableArray alloc] init];
[stringArray addObject:@"First String"];
[stringArray addObject:@"Second String"];
And if you try to add another object of a different type:
[stringArray addObject:[NSNumber numberWithInt:5]];
You’ll get a warning similar to:
Incompatible pointer types sending 'NSNumber * _Nonnull' to parameter of type 'NSString * _Nonnull'`
If you needed a strictly typed collection of data, this example alone will give you a strong reason. The problem with collection classes is that there’s no way for them to check whether the object we want to store is of the same type of what we want to store. Therefore they can’t validate the object’s type we want to pass to them. This means accidental insertion of an object with different type is very likely.
Note: Generics work for both base class and subclass.
The responsibility for using the correct type is our job. If we use a wrong type and a message that an object doesn’t respond is sent, a runtime error will occur.

Things to Remember

The language did not change nor had been updated. So you can still crash at runtime if your code works around this.
What is the result of introducing lightweight generics in Xcode 7 then?
The necessity to typecast is reduced. The responsibility of tracking an object type does not lie to the developer alone, but to the compiler as well. The code will be cleaner, maintainable, readable, safer, and may result to less error.
Angelo Villegas is an iOS Software Engineer from Manila. Building native iOS apps using Xcode, Objective-C and Swift, contribution to the open-source community and writing articles on AngeloVillegas.com