Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS __kindof NSArray?

I've been checking out iOS 9 new features as a developer and some of them like the StackView look awesome.

When I went the the header file of UIStackView I saw this:

@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *arrangedSubviews; 

What is the __kindof on NSArray*. Are we able to specify a type on a NSArray * now?

Little test:

@interface DXTEST () @property (strong, nonatomic) NSMutableArray <__kindof NSString *>  *strings; @end  @implementation DXTEST  - ( instancetype ) init {     self = [super init];      if( self ) {         _strings = [NSMutableArray new];          [_strings addObject:@(1)]; <-- compiler warning wieeeeee     }      return self; }  @end 
like image 427
Haagenti Avatar asked Jul 14 '15 06:07

Haagenti


People also ask

What is NSArray?

NSArray creates static arrays, and NSMutableArray creates dynamic arrays. You can use arrays when you need an ordered collection of objects. NSArray is “toll-free bridged” with its Core Foundation counterpart, CFArrayRef . See Toll-Free Bridging for more information on toll-free bridging.

What's a difference between NSArray and NSSet?

The main difference is that NSArray is for an ordered collection and NSSet is for an unordered collection. There are several articles out there that talk about the difference in speed between the two, like this one. If you're iterating through an unordered collection, NSSet is great.

Can NSArray contain nil?

arrays can't contain nil.


1 Answers

Sadly the currently top voted answers are a bit incorrect.

You actually can add any subclass of <T> to a generic collection:

@interface CustomView : UIView @end @implementation CustomView @end  NSMutableArray<UIView *> *views; UIView *view = [UIView new]; CustomView *customView = [CustomView new]; [views addObject:view]; [views addObject:customView];//compiles and runs! 

But when you'll try to retrieve the object, it will be strictly typed as <T> and will require casting:

//Warning: incompatible pointer types initializing  //`CustomView *` with an expression of type `UIView * _Nullable` CustomView *retrivedView = views.firstObject; 

But if you'll add __kindof keyword the returned type will be changed to kindof T and no casting will be required:

NSMutableArray<__kindof UIView *> *views; <...> CustomView *retrivedView = views.firstObject; 

TLDR: Generics in Objective-C can accept subclasses of <T>, __kindof keyword specifies that return value can also be subclass of <T>.

like image 112
Artem Abramov Avatar answered Sep 17 '22 17:09

Artem Abramov