Objective-C Generics

WWDCを用いて、OS X 10.11ベータとiOS 9ベータ版が公開され、XCode 7のベータ版も公開されました。
XCode 7ベータ版から追加されたObjective-CのGenericsについて簡単ですが共有したいと思います。

Objective-C Generics

0. Lightweight Generics

Xcode 7ベータから対応され、Foundation Collectionに適用されています。
(NSArray, NSMutableArray, NSSet, NSMutableSet, NSOrderedSet, NSMutableOrderedSet, NSDictionary, NSMutableDictionary, NSHashTable, NSMapTable)

1. Syntax

Objective-CのGenericsは次のように表現できます。

NSArray<NSString*> *strings = [[NSArray<NSString*> alloc] init];

2. Type check

残念ながら、Objective-CのGenericsはタイプパラメータの検査がJavaやC#に比べて厳密ではありません。
もし、NSArrayの配列にNSNumberオブジェクトを入れようとすると、警告が出るだけでコンパイルが成功します。

Why?

Objective-C Genericsの実装は、idタイプを利用するからです。詳細は以下の実装例を参考にしてください。

3. Genericsを実装

クラスを定義すると、次のように定義できます。

@interface VPStack<__covariant ElemType> : NSObject
-(void)push:(ElemType)element;
-(ElemType)pop;
@end

しかし、実装部idタイプを用いて実装します。

@implementation VPStack
-(instancetype)init {...}
-(void)push:(id)element {...}
-(id)pop {...}
@end

このように実装されたクラスは、次のように使用できます。

VPStack<NSString*>* stack = [[VPStack<NSString*> alloc] init];
[stack push:@"element1"];
[stack push:@1];

3行目のように定義されたタイプと異なるタイプを入れると、次のような警告が表示されます。
しかし、実装がidタイプになっているので、通常動作します。

Incompatible pointer types sending ’NSNumber *’ to parameter of type ’NSString *'

 

TOAST Meetup 編集部

TOASTの技術ナレッジやお得なイベント情報を発信していきます
pagetop