2016年03月22日

Swift: クラスの判定


Objective-Cでクラスを判定してなんらかの処理をする場合を、Swiftで実現するのはどうするのか。例えば、isKindOfClass: とか、isMemberOfClass: とかの処理。

「if ( [object isKindOfClass:[Root class]] )」は、そのオブジェクトが、Rootクラスのインスタンスかまたはそのサブクラスのいずれかのインスタンスであれば真になる。もし、判定後にそのクラスとしてなんらかの操作を行うのであれば、キャストして代入すればよい。「Sub1 *sub = (Sub1*)object;」のようにする。

一方、そのインスタンスそのものである時だけ真にしたい場合には、「isMemberOfClass:」を使う。
#import 

@interface Root : NSObject
@end

@implementation Root
@end

@interface Sub1 : Root
@end

@implementation Sub1
@end

@interface Sub2 : Root
@end

@implementation Sub2
@end

int main(int argc, const char * argv[]) {
@autoreleasepool {
id array = @[
[[Root alloc] init],
[[Sub1 alloc] init],
[[Sub2 alloc] init],
];
for (id object in array) {
if ( [object isKindOfClass:[Root class]] ) {
NSLog(@"The object is Root.");
}
if ( [object isKindOfClass:[Sub1 class]] ) {
NSLog(@"The object is Sub1.");
}
if ( [object isKindOfClass:[Sub2 class]] ) {
NSLog(@"The object is Sub2.");
}
}
for (id object in array) {
if ( [object isMemberOfClass:[Root class]] ) {
NSLog(@"The object is Root.");
}
if ( [object isMemberOfClass:[Sub1 class]] ) {
NSLog(@"The object is Sub1.");
}
if ( [object isMemberOfClass:[Sub2 class]] ) {
NSLog(@"The object is Sub2.");
}
}
}
return 0;
}


SwiftでisKindOfClass:に相当するのは is 演算子になる。また判定後にそのクラスのオブジェクトとして使用するのであれば、as を使う。キャストが失敗する可能性があるのでオプショナル型のアンラップ処理が必要。

Swiftで、isMemberOfClass:に相当するのは、型としての比較。「object.dynamicType == Root.self」。dynamicTypeはそのインスタンスが今代入されている変数の型ではなく本当の型を返す。一方、型名(クラス名)にselfを付けると型そのものになるみたい。

Objective-Cのキャストに相当する操作は as? 演算子を使う。指定した型にダウンキャストできなければ nil が代入される。

class Root {}
class Sub1: Root {}
class Sub2: Root {}

let objects = [
Root(),
Sub1(),
Sub2(),
]
for object in objects {
if object is Root { // Warning: 'is' test is always true
print("The object is Root.")
}
if object is Sub1 {
print("The object is Sub1.")
}
if object is Sub2 {
print("The object is Sub2.")
}
}
for object in objects {
if let o = object as? Root { // Warning: Conditional cast from 'Root' always succeeds
print("The object as Root.")
}
if let o = object as? Sub1 {
print("The object as Sub1.")
}
if let o = object as? Sub2 {
print("The object as Sub2.")
}
}
for object in objects {
if object.dynamicType == Root.self {
print("The object == Root.")
}
if object.dynamicType == Sub1.self {
print("The object == Sub1.")
}
if object.dynamicType == Sub2.self {
print("The object == Sub2.")
}
}
for object in objects {
print(object.dynamicType)
}

ラベル:クラス Swift
posted by 永遠製作所 at 12:12| 東京 ☀| Comment(0) | TrackBack(0) | Swift | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバック