2011-12-19 7 views
4

クラスを実行時にobjective-cで定義することは可能ですか?
など。オブジェクトを定義し、それを作成して実行時に使用するXMLファイルを受け取りますか?Objective-cクラスランタイム定義

+0

XMLでivarsやメソッドを使用して、まったく新しいクラスの型を宣言することを意味しますか?XMLによって提供される状態(ivars、プロパティなど)を持つ既存のクラスのインスタンスを作成することを意味しますか? –

+0

もしあなたが(そしておそらく)できることがあっても、本当の質問は... –

+0

Tim、全く新しいクラスタイプを作成する最初のオプションです。 –

答えて

6

はい、このコードをチェックアウトスニペット、私はCのメソッドを使用して、ここでクラスを作成し、1つのプロトコル定義(簡略化のためのメッセージを作成する際に呼び出します)...

MyCObject.h

#import <Foundation/Foundation.h> 

@protocol MyCObj_methods<NSObject> 

-(NSString *) getString; 
-(int) getInt; 
+(NSString *) someStaticMethod; 

@end 

typedef id<MyCObj_methods> MyCObj; 
extern Class MyCObj_class; 

__attribute__((constructor)) 
void MyCObj_initialize(); 

MyCObj MyCObj_alloc(  id self,  SEL _cmd); 
MyCObj MyCObj_new(   id self,  SEL _cmd); 

NSString *MyCObj_someStaticMethod (id self, SEL _cmd); 

MyCObj MyCObj_init(  MyCObj self, SEL _cmd); 
NSString *MyCObj_getString(MyCObj self, SEL _cmd); 
int MyCObj_getInt(   MyCObj self, SEL _cmd); 

MyCObject.m

#import "MyCObject.h" 
#import <objc/Object.h> 
#import <objc/runtime.h> 

static Class myStaticClass; 
Class MyCObj_class; 

typedef struct 
{ 
    Class isa; 
    NSString *myString; 
    int myInt; 
} MyCObj_t; 

void MyCObj_initialize(void); 

__attribute__((constructor)) 
void MyCObj_initialize() 
{ 
    MyCObj_class = objc_allocateClassPair([NSObject class], "MyCObj", 0); 
    objc_registerClassPair(MyCObj_class); 

    myStaticClass = object_getClass(MyCObj_class); 

    class_addMethod(MyCObj_class, @selector(init),  (IMP)MyCObj_init,  "@@:"); 
    class_addMethod(MyCObj_class, @selector(getString), (IMP)MyCObj_getString, "@@:"); 
    class_addMethod(MyCObj_class, @selector(getInt), (IMP)MyCObj_getInt,  "[email protected]:"); 

    class_addMethod(myStaticClass, @selector(alloc),   (IMP)MyCObj_alloc, "@@:"); 
    class_addMethod(myStaticClass, @selector(new),    (IMP)MyCObj_new, "@@:"); 
    class_addMethod(myStaticClass, @selector(someStaticMethod), (IMP)MyCObj_someStaticMethod, "@@:"); 
} 

MyCObj MyCObj_alloc(id self, SEL _cmd) 
{ 
    return (MyCObj) class_createInstance(MyCObj_class, sizeof(MyCObj_t) - sizeof(Class)); 
} 

MyCObj MyCObj_new(id self, SEL _cmd) 
{ 
    return (MyCObj) [[MyCObj_class alloc] init]; 
} 

NSString *MyCObj_someStaticMethod(id self, SEL _cmd) 
{ 
    return @"Some Static Method"; 
} 

MyCObj MyCObj_init(MyCObj self, SEL _cmd) 
{ 
    struct objc_super super = { .receiver = self, .super_class = [NSObject class] }; 

    if ((self = (MyCObj) objc_msgSendSuper(&super, _cmd))) 
    { 
     ((MyCObj_t *) self)->myString = @"hello world!"; 
     ((MyCObj_t *) self)->myInt = 15; 
    } 

    return self; 
} 

NSString *MyCObj_getString(MyCObj self, SEL _cmd) 
{ 
    return ((MyCObj_t *) self)->myString; 
} 

int MyCObj_getInt(MyCObj self, SEL _cmd) 
{ 
    return ((MyCObj_t *) self)->myInt; 
} 

使用法:

MyCObj obj = [MyCObj_class new]; 
NSLog(@"%@ %i %@", [obj getString], [obj getInt], [MyCObj_class someStaticMethod]); 
+1

それをやめてください。あなたは子供たちを怖がらせています(私が私を意味する):) +1 –

+0

@TimKemp実際には、私はこの質問を見たときにこれを書いていました...これのアイデアは、私はそれをテストしたいと思っていました...これはブロックでも行うことができます。そのようなブロックを使ってオブジェクトを作成するのは実際には本当にクールです... –

+1

本当に華麗です。私はObjective Cでランタイムバインディングとセレクタ駆動のものをどこまで押し込むことができるか不明確でした。それは私が思っていた以上のものであることが判明しました。バロックの垣間見ていただきありがとうございます(実際にはこれは結局のところ実用的ではありませんが、その邪悪にある美しさがあります)。 –

2

はい、ですが、実行時に型を作成し、メソッドとその記憶域を定義するためにobjcランタイムを使用しますが、これは非常に珍しいことです。

あなたが使用するインターフェイスは、ランタイムヘッダobjc/runtime.hであり、そしてあなたが望む通話等objc_allocateClassPairclass_addMethodclass_addIvar、あるために行われる作業のかなりのビットは明らかにありますが、クラスとそのレイアウト、セレクタを作成し、そのようなものはXML記述からのものです。したがって、可能ですが、無料ではありません。

+2

あなたはこれを拡張する*を持っています:) –

+0

しかし、本当に、あなたはすべきではありません... –

+0

@Tim Kemp lol - 私は単純に「実行時にクラスを定義することは可能ですか? - しかし私は今それを拡張しました=) – justin

5

はい。完全に可能です。詳細については、Objective-C Runtime Programming Guideを参照してください(関連ガイド&ドキュメントを含む)。

ジャスティンは言ったように、この経路をとるのは非常に非典型的です。 XMLデータを読み込んでいる場合、ほとんどの場合、XMLは厳密なDTDまたはスキーマである明確な構造を持たなければならないというキャストであり、規律のある明確なデータモデルではるかに良いでしょう(コアデータまたは直接実装を介して)あなたのアプリにコンパイルされ、XMLをロードします。これにより、より厳密な検証が可能になり、大幅に簡単になります。

「自由形式データ消費」の聖杯は魅力的ではありませんが、その道の下には狂気と多くの悲惨な話があります。

関連する問題