BOOL CreateClassDefinition( const char * name,
| |
const char * superclassName )
| |
{
| |
struct objc_class * meta_class;
| |
struct objc_class * super_class;
| |
struct objc_class * new_class;
| |
struct objc_class * root_class;
| |
va_list args;
| |
| |
//
| |
// スーパークラスが存在しており、同じ名前のクラスを誰かが
| |
// すでに実装していないことを保証する
| |
//
| |
super_class = (struct objc_class *)objc_lookUpClass (superclassName);
| |
if (super_class == nil)
| |
{
| |
return NO;
| |
}
| |
| |
if (objc_lookUpClass (name) != nil)
| |
{
| |
return NO;
| |
}
| |
| |
// ルートクラスを探す
| |
root_class = super_class;
| |
while( root_class->super_class != nil )
| |
{
| |
root_class = root_class->super_class;
| |
}
| |
| |
// クラスとそのメタクラス用に領域を割り当てる
| |
new_class = calloc( 2, sizeof(struct objc_class) );
| |
meta_class = &new_class[1];
| |
| |
// クラスのセットアップ
| |
new_class->isa = meta_class;
| |
new_class->info = CLS_CLASS;
| |
meta_class->info = CLS_META;
| |
| |
//
| |
// クラス名のコピーを作成する。
| |
// 効率のため、メタクラスとクラス自体で、この名前のコピーを
| |
// 共有するが、これはランタイムの必須条件ではない
| |
//
| |
//
| |
new_class->name = malloc (strlen (name) + 1);
| |
strcpy ((char*)new_class->name, name);
| |
meta_class->name = new_class->name;
| |
| |
//
| |
// 空のメソッドリストを割り当てる。
| |
// メソッドの追加は後でも可能。
| |
//
| |
new_class->methodLists = calloc( 1, sizeof(struct objc_method_list *) );
| |
meta_class->methodLists = calloc( 1, sizeof(struct objc_method_list *) );
| |
| |
//
| |
// クラス定義を正しい階層に接続する:
| |
// クラスをスーパークラスに接続。
| |
// メタクラスをスーパークラスのメタクラスに接続。
| |
// メタクラスのメタクラスを
| |
// ルートクラスに接続。
| |
new_class->super_class = super_class;
| |
meta_class->super_class = super_class->isa;
| |
meta_class->isa = (void *)root_class->isa;
| |
| |
// 最後に、クラスをランタイムに登録する
| |
objc_addClass( new_class );
| |
return YES;
| |
}
| |