Using typed NSArray* in Objective-C

In Objective-C, for example, arrays can hold any object type:

NSArray * array = @[@"Hello", @1, @{@"key": @2} [NSObject new], [NSNull null]];
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
// Do something with the object
}];

In the previous code, we see id _Nonnull obj as being the first parameter of our enumeration block. This is very far from being useful as a consumer of the array has no idea what kind of objects are contained. At compile time, it is impossible to enforce a safe usage of the arrays. This is where lightweight generics come in:

NSArray<NSString *> * stringArray = @[@"Hello", @1];
// WARNS: Object of type 'NSNumber *' is not compatible with array element type 'NSString *'

While the compiler doesn't explicitly prevent us from initializing the array, a warning is issued with the correct resolution. In this case, only strings can be added to stringArray.