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;
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.