I've noticed the Objective-C keyword __kindof
in system framework header files, but I've never used it in my own code. What's the purpose of the keyword? Is it necessary? Is it useful?
Apple doesn't provide much documentation for __kindof
, but I did find an explanation in a WWDC session video from 2015 when the keyword was introduced. (No, I don't consider WWDC videos to be documentation!) The primary purpose seems to be to provide backward compatibility in support of new Objective-C features such as generics (which were themselves introduced primarily in support Swift interoperability). The WWDC video uses the NSView subviews
property as an example. Here's how it was declared before 2015.
@property(copy) NSArray *subviews;
And here's how it's declared with generics, after 2015.
@property(copy) NSArray<__kindof NSView *> *subviews;
What would happen if this property were declared without the __kindof
keyword? Then the following code, which was perfectly fine prior to 2015, would produce the build warning "initializing 'NSButton *' with an expression of type 'NSView *'".
NSButton *button = myContainerView.subviews[0];
Of course NSButton
is a subclass of NSView
, so the build warning doesn't necessarily indicate a bug, and introducing generics into the system framework headers without __kindof
would produce countless build warnings in extant source code. Some (self-hating) programmers enjoy fixing new build warnings, but most (sane) programmers do not. Thus, __kindof
is a decent compromise in this case. It enables build warnings for obvious bugs — when the two classes are completely unrelated — without greatly disturbing working code.
Should you use __kindof
in your own code? In general, no. The WWDC video warns, "Use sparingly". Again, the primary purpose seems to be to provide backward compatibility with existing code. If you're developing a framework with a backward compatibility requirement, then __kindof
may be kind of useful. But otherwise, it's kind of useless. There's little reason to use the keyword in newly written application code. If you don't want build warnings, then don't use generics in the first place, or just typecast explicitly when necessary. And if you're worried about bugs, do a runtime check of the type.
While it's true that <__kindof Type*>
would catch some bugs that wouldn't be caught without generics, keep in mind that it would also hide some bugs that would be caught with generics. Which kind of bug is more likely, assuming an entirely wrong class, or assuming the wrong subclass? If the latter is more likely, then __kindof
would be more harm than help. Yes, choices are always trade-offs. Cue Econ 101 video.