objective c - iOS __kindof NSArray? -
i've been checking out ios 9 new features developer , of them stackview awesome.
when went the header file of uistackview saw this:
@property(nonatomic,readonly,copy) nsarray<__kindof uiview *> *arrangedsubviews;
what __kindof on nsarray*. able specify type on 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
are able specify type on nsarray * now?
yes, through objective-c's new lightweight generics. in example provided, have property of type nsarray
, which accept elements uiview
s.
now, can specified follows (without __kindof
).
@property(nonatomic,readonly,copy) nsarray<uiview *> *arrangedsubviews;
and in case, array accept objects class uiview
, not objects subclasses of uiview
. __kindof
declaration marks array's generic type 1 can accept both instances of uiview
class, , instances of of uiview
's subclasses.
edit:
i've removed bulk of original answer since mistakenly thought specifying type of array prevent inserting objects of incorrect type, , not case. (thanks artem abramov pointing out. please see answer below additional details)
objective-c's generics seem exist give type information when accessing elements of generic collection. example, consider following code adds uiview
, uiimageview
nsmutablearray<uiview *>
. both objects inserted array without complaints compilers or runtime, when try access elements, you're warned compiler if type of variable other generic type of array (uiview
), if it's 1 of uiview
's subclasses.
nsmutablearray<uiview *> *subviews = [[nsmutablearray alloc] init]; [subviews addobject:[[uiview alloc] init]]; // works [subviews addobject:[[uiimageview alloc] init]]; // works uiview *sameview = subviews[0]; // works uiimageview *sameimageview = subviews[1]; // incompatible pointer types initializing 'uiimageview *' expression of type 'uiview *' nslog(@"%@", nsstringfromclass([sameview class])); // uiview nslog(@"%@", nsstringfromclass([sameimageview class])); // uiimageview
now, produces compile time warning, not crash @ runtime. key difference between , same example array's generic type marked __kindof
, compiler won't complain if try access ones of elements, , store result in variable who's type uiview
or 1 of subclasses.
nsmutablearray<__kindof uiview *> *subviews = [[nsmutablearray alloc] init]; [subviews addobject:[[uiview alloc] init]]; // works [subviews addobject:[[uiimageview alloc] init]]; // works uiview *sameview = subviews[0]; // no problem uiimageview *sameimageview = subviews[1]; // no complaints now! nslog(@"%@", nsstringfromclass([sameview class])); // uiview nslog(@"%@", nsstringfromclass([sameimageview class])); // uiimageview
Comments
Post a Comment