Reputation: 42449
Xcode 7 added the __kindof
decorator to object declarations:
KindOf. Objects declared as
__kindof
types express "some kind of X" to the compiler and can be used within generic parameters to constrain types to a particular class or its subclasses. Using__kindof
allows constraints to be more flexible than an explicit class, and more explicit than just usingid
.
The most obvious use case for __kindof
is with collection types to explicitly state what kind of objects will be in a particular collection. From the UIStackView
header:
- (instancetype)initWithArrangedSubviews:(NSArray<__kindof UIView *> *)views; // Adds views as subviews of the receiver.
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *arrangedSubviews;
This explicitly states that each NSArray
will contain objects that are or inherit from UIView
.
But there are some cases where __kindof
is used on a non-collection typed object, such as in the UIStoryboardSegue
header:
@property (nonatomic, readonly) __kindof UIViewController *sourceViewController;
@property (nonatomic, readonly) __kindof UIViewController *destinationViewController;
What does the __kindof
decorator change on non-collection-type objects?
Upvotes: 3
Views: 385
Reputation: 42449
The most obvious case is when casting types:
UIViewController *vc = [[UIViewController alloc] init];
// SomeViewController inherits from UIViewController
SomeViewController *someViewController = vc; // Warning: Incompatible pointer type initializing 'SomeViewController *' with an expression of type 'UIViewController *'
__kindof UIViewController *otherVC = [[UIViewController alloc] init];
SomeViewController *someVC = otherVC; // no warning
This is why in a UIViewController
's prepareForSegue
method, casting segue.destinationViewController
to another UIViewController
subclass does not show a warning:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
SomeViewController *someVC = segue.destinationViewController; // no warning
// ...
}
Upvotes: 4