在Objective C中构建动态类

时间:2010-03-15 13:41:39

标签: objective-c ruby dynamic objective-c-runtime

我是一位有能力的红宝石程序员。昨天我决定最终尝试使用Apple的Cocoa框架。帮我看看ObjC的方式吗?

我正试图绕过objc_allocateClassPairobjc_registerClassPair。我的目标是动态生成一些类,然后能够像任何其他类一样使用它们。这是否适用于Obj C?

分配并注册了类A后,我在调用[[A alloc] init];时遇到编译错误(它显示为'A' Undeclared)。我只能使用运行时的A方法实例化objc_getClass。有没有办法告诉编译器A并传递消息,就像我NSString一样?编译器标志还是什么?

我有10个左右的其他类(BC,...),都具有相同的超类。我想直接在代码([A classMethod][B classMethod],...)中向他们发送消息,而不需要objc_getClass。我想在这里过于动态还是只是拙劣地实施我的实施?它看起来像这样......

 NSString *name = @"test";  
 Class newClass = objc_allocateClassPair([NSString class], [name UTF8String], 0);  
 objc_registerClassPair(newClass);  

 id a = [[objc_getClass("A") alloc] init];  
 NSLog(@"new class: %@ superclass: %@", a, [a superclass]);  
 //[[A alloc] init]; blows up.

4 个答案:

答案 0 :(得分:5)

[[A alloc] init];爆炸的原因是编译器不知道A的含义。编译器永远不会知道A就在那里。

编辑:此外,它看起来像你想要的是:

@interface A : NSObject {
  NSString *myString;
}

- (id)initWithString:(NSString *)string;

- (void)doItToIt;

@end

或者

@interface NSString (MyPrivateExtension)

- (void)doItToIt;

@end

答案 1 :(得分:1)

当您使用Objective-C语言定义类时,编译器会定义一个新类型。当您动态创建类时,编译器不了解该类型,因此您唯一的选择是将该类用作id,并动态地向其发送消息。 Ruby是一种动态类型语言,在运行时定义类时可能使用与编译器相同的机制。

答案 2 :(得分:1)

查看http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.htmlhttps://github.com/mikeash/MAObjCRuntime

它描述了您正在尝试实现的目标,并提供了对原始Objective-C运行时调用的良好抽象。

答案 3 :(得分:0)

看一下可以做到这一点并且是开源的精彩F-ScriptFSClass。 FSClass定义了一个可以在运行时进行子类化的元类。

它通过使用 objc_allocateClassPair objc_registerClassPair 工作,但是还有很多其他的东西(超出我!)可能会有所帮助。