Objective-C Generics
Goichi Hirakawa
About Me
• 平川 剛一 (Goichi Hirakawa)
• @gooichi
• OS X / iOSソフトウェアエンジニア(フリー)
• GyazSquare / GitHub
• Mailer、デバイス制御、MDM系など
• Objective-C歴XX年
• 初めて触れたのはNextStep…
New Objective-C Features
Objective-CとSwiftをより簡単で効率的に連携させ
るためのXcode 7からの新機能:
• Generics
• Nullability (Updated)
• KindOf Types
• New macros for Swift
New Objective-C Features
Objective-CとSwiftをより簡単で効率的に連携させ
るためのXcode 7からの新機能:
• Generics
• Nullability (Updated)
• KindOf Types
• New macros for Swift
Agenda
• What s Generics?
• Objective-C Generics
• Backward Compatibility
• Generic Classes (iOS 9)
• Variances
• KindOf Types
What s Generics?
• 型に依存しない共通の処理やアルゴリズムを型パラメータ
(Type Parameter)を用いて定義し、汎用化する機能
• ジェネリックプログラミングの仕組み
• 言語により呼び名、機能は若干異なる
• テンプレート(C++)、ジェネリクス(Java、Swiftな
ど)、ジェネリック(MS系言語)、パラメータ化され
た型(Scala)等々
Objective-C Generics
• 他言語と比べ、Lightweight(軽量、簡易)
• APIの表現力を向上させる
• コレクションをより使いやすくする
• Swiftにより型情報がインポート
• より良い静的型チェックを可能にする
• Xcode 7(LLVM 7.0.0)以降
Before Using Generics
Objective-C
@interface UIView
@property (nonatomic, copy ,readonly) NSArray *subviews;
@end
Swift
class UIView {
var subviews: [AnyObject] { get }
}
After Using Generics
Objective-C
@interface UIView
@property (nonatomic,readonly,copy) NSArray<UIView *>*subviews;
@end
Swift
class UIView {
var subviews: [UIView] { get }
}
Static Type Checking
• 型に関する警告が表示される
• ただし、以下は警告は出ない→正しい(後方互換性参照)
Backward Compatibility
• 型消去(Type Erasure)モデルでバイナリ互換
• Objective-Cランタイムに変更なし
• コード生成に影響なし 
• 暗黙の変換によるソース互換性
NSArray<NSString *> *strings = ...;  
NSArray *array = ...;  
array = strings; // OK, 型引数が削除  
strings = array; // OK, 型引数が追加  
Generic Classes (iOS 9)
• NSArray、NSSetとNSDictionary
• これらの型情報はSwiftによりインポートされる
• それ以外のジェネリクス対応クラス
• NSCache、NSEnumerator、NSHashTable、
NSMapTable、NSOrderedSet、PHFetchResult、
および、これらのMutableクラスもジェネリクス対応
• これらの型情報はSwiftによりインポートされない
Variances
• 共変性(covariant)
• A←Bのとき、X<A>変数にX<B>実体を割り当て可能
• 反変性(contravariant)
• A←Bのとき、X<B>変数にX<A>実体を割り当て可能
• 不変性(invariant)
• X<A>変数にはX<A>以外の実体は割り当て不可
Objective-C Generics Variances
• 新しいキーワードの追加
• 共変性:X<__covariant ObjectType>
• NSArray、NSDictionary、NSOrderedSet、NSSet
• 反変性:X<__contravariant ObjectType>
• 現状該当クラスなし
• 不変性:何もつけない(デフォルト)
• 上記クラス以外すべて
Type Safety for Typed Collections
• NSArrayはcovariant(共変)
NSArray<UIView *> *views;
NSArray<UIResponder *> *responders = views; // OK
• NSMutableArrayはinvariant(不変)
UIViewController *viewController;
NSMutableArray<UIView *> *views;
NSMutableArray<UIResponder *> *responders = views; // NG
[responders addObject:viewController];
warning: Incompatible pointer types initializing
'NSMutableArray<UIResponder *> *' with an expression of
type 'NSMutableArray<UIView *> *'
KindOf Types
• 型付きコレクションを使わない場合(従来コード)
@interface UIView (UIViewHierarchy)
@property(nonatomic,readonly,copy) NSArray *subviews;
@end
[view.subviews[0] setTitle:@YES forState:UIControlStateNormal]; // OK
• 型付きコレクションを使う場合→エラー
@interface UIView (UIViewHierarchy)
@property(nonatomic,readonly,copy) NSArray<UIView *> *subviews;
@end
[view.subviews[0] setTitle:@YES forState:UIControlStateNormal]; // NG
error: No visible @interface for 'UIView' declares the selector
'setTitle:forState:'
KindOf Types
• 型付きコレクションは、型安全になり、Swiftからも利用しやす
くなるが、従来のコードでエラーとなるケースが発生
• 新しいキーワードの追加
• __kindof
• __kindof MyClass: MyClassまたはMyClassの派生クラス
@interface UIView (UIViewHierarchy)
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
@end
[view.subviews[0] setTitle:@YES forState:UIControlStateNormal]; // OK
Conclusion
• Objective-Cジェネリクスは、機能的にはLightweightであるが、

以下の理由より既存コードに適用する価値はある:
• 静的型チェック
• Swiftの型情報インポート
• バイナリ互換
• KindOf型はObjective-Cジェネリクスとの組み合わせだけでなく、
既存コードのid型との置き換えでも利用可能
• id型よりも型安全になり、Swiftからも使いやすくなる

Objective-C Generics