Типизация в Objective-C проста как:
NSArray *threeViews = @[[UIView new], [UIView new], [UIView new]];
UIView *firstView = (UIView *)threeViews[0];
Однако, что происходит, если первый объект не UIView
и вы пытаетесь использовать его:
NSArray *threeViews = @[[NSNumber new], [UIView new], [UIView new]];
UIView *firstView = (UIView *)threeViews[0];
CGRect firstViewFrame = firstView.frame; // CRASH!
Это потерпит крах. И в этом случае легко найти такой сбой, но что, если эти строки находятся в разных классах, а третья строка выполняется только один раз в 100 случаях. Бьюсь об заклад, ваши клиенты находят этот сбой, а не вы! Возможное решение - ранний сбой , например:
UIView *firstView = (UIView *)threeViews[0];
NSAssert([firstView isKindOfClass:[UIView class]], @"firstView is not UIView");
Эти утверждения выглядят не очень хорошо, поэтому мы могли бы улучшить их с помощью этой удобной категории:
@interface NSObject (TypecastWithAssertion)
+ (instancetype)typecastWithAssertion:(id)object;
@end
@implementation NSObject (TypecastWithAssertion)
+ (instancetype)typecastWithAssertion:(id)object {
if (object != nil)
NSAssert([object isKindOfClass:[self class]], @"Object %@ is not kind of class %@", object, NSStringFromClass([self class]));
return object;
}
@end
Это намного лучше:
UIView *firstView = [UIView typecastWithAssertion:[threeViews[0]];
P.S. Для коллекций тип безопасности Xcode 7 гораздо лучше, чем типизирование - generics