見えないクラス群

Objective-Cは大変面白い言語です。こんな問題を用意してみました。このプログラムのNSLogで出力される文字列は、いったいどうなるでしょうか。すべてクラス名が出力されます。

#import <foundation /Foundation.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

	NSString *string1 = [NSString stringWithString:@"http://dev.activebasic.com/"];
	NSString *string2 = [string1 stringByAppendingPathComponent:@"OverTaker"];

	NSLog( [string1 className] );
	NSLog( [string2 className] );

	NSURL *URL = [NSURL URLWithString:string2];
	NSData *data = [NSData dataWithContentsOfURL:URL];

	NSLog( [URL className] );
	NSLog( [data className] );
	NSLog( [[string2 dataUsingEncoding:NSUTF8StringEncoding] className] );

	NSNumber *num1 = [NSNumber numberWithInt:0];
	NSNumber *num2 = [NSNumber numberWithBool:YES];

	NSLog( [num1 className] );
	NSLog( [num2 className] );

	NSLog( [[NSDate date] className] );
	NSLog( [[NSValue valueWithSize:NSMakeSize(0, 0)] className] );

    [pool drain];
    return 0;
}

ちなみに、リファレンスを見る限りでは、このような出力が予想されます。

NSString
NSString
NSURL
NSData
NSData
NSNumber
NSNumber
NSDate
NSValue

ブログのネタにするのですから、当然こんな結果になるとは思っていない方が多いと思われます。しかし、これほどまでに見たことのないクラス群が返ってくると、Objective-Cをつい先日始めたような方々は、びっくりされるのではないかと思います。以下、実行結果です。

NSCFString
NSPathStore2
NSURL
NSConcreteData
NSConcreteMutableData
NSCFNumber
NSCFBoolean
__NSCFDate
NSConcreteValue

個人的に予想外だったのは、NSConcreteMutableDataと__NSCFDateです。
いつの間にかプログラマも知らないクラスを扱っているとは、とても変な気分にさせます。しかし、これができるからこそObjective-Cであり、簡潔な仕組みで複雑なクラスを作ることができるのです。

察している方々もいると思いますが、これは抽象クラスと非常に似た概念です。NSStringという抽象クラスだけが表に出ており、それの実態である各種用途に特殊化したNSStringは隠されている。NSCFStringとNSPathStoreはそんな関係が予想されます。ちなみに、NSCFStringはCからも扱える驚きのクラスなのですが、それはまた別の話になりますので飛ばします。

なかなか説明が難しいのですが、もちろんAppleの優秀なドキュメントに、このデザインパターンについて書かれています。興味を持った方は、そちらをご覧になってください。

Cocoa Fundamentals Guide > Cocoaオブジェクト > クラスクラスタ

コメント投稿