在 Objective C 中构建动态类
我是一个有点称职的 Ruby 程序员。昨天我决定最终尝试一下 Apple 的 Cocoa 框架。帮助我以 ObjC 的方式看待事物?
我正在尝试了解 objc_allocateClassPair 和 objc_registerClassPair 。我的目标是动态生成一些类,然后能够像使用任何其他类一样使用它们。这在 Obj C 中有效吗?
分配并注册类 A
后,我在调用 [[A alloc] init];
时收到编译错误(它显示 'A' Undeclared
)。我只能使用运行时的 objc_getClass 方法实例化 A。有什么方法可以告诉编译器有关 A
的信息并像我那样向它传递消息 NSString
吗?编译器标志什么的?
我有大约 10 个其他类(B
、C
...),它们都具有相同的超类。我想直接用代码([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.
I'm a somewhat competent ruby programmer. Yesterday I decided to finally try my hand with Apple's Cocoa frameworks. Help me see things the ObjC way?
I'm trying to get my head around objc_allocateClassPair
and objc_registerClassPair
. My goal is to dynamically generate a few classes and then be able to use them as I would any other class. Does this work in Obj C?
Having allocated and registered class A
, I get a compile error when calling [[A alloc] init];
(it says 'A' Undeclared
). I can only instantiate A
using runtime's objc_getClass
method. Is there any way to tell the compiler about A
and pass it messages like I would NSString
? A compiler flag or something?
I have 10 or so other classes (B
, C
, …), all with the same superclass. I want to message them directly in code ([A classMethod]
, [B classMethod]
, …) without needing objc_getClass
. Am I trying to be too dynamic here or just botching my implementation? It looks something like this…
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
[[A alloc] init];
崩溃的原因是编译器不知道A
的含义。编译器永远不知道A
是否存在。编辑:另外,看起来你想要的是:
或者也许
The reason that
[[A alloc] init];
blows up is that the compiler has no clue whatA
means. The compiler never knows thatA
is even there.Edit: Also, it looks like what you want is:
or perhaps
当您在 Objective-C 语言中定义类时,编译器会定义一个新类型。当您动态创建一个类时,编译器不知道该类型,因此您唯一的选择就是使用该类作为 id,并动态地向其发送消息。 Ruby 是一种动态类型语言,在运行时定义类时可能使用与编译器相同的机制。
When you define a class in the Objective-C language, the compiler defines a new type. When you create a class dynamically, the compiler has no knowledge of that type, so your only choice is to use the class as an id, and send messages to it dynamically. Ruby is a dynamically typed language that likely uses the same mechanisms as the compiler when defining classes at runtime.
看看 http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html 和 https://github.com/mikeash/MAObjCRuntime
它描述了您想要实现的目标,并提供了对原始数据的良好抽象Objective-C 运行时调用。
Have a look at http://www.mikeash.com/pyblog/friday-qa-2010-11-6-creating-classes-at-runtime-in-objective-c.html and https://github.com/mikeash/MAObjCRuntime
It describes just what you're trying to achieve and provides a nice abstraction over raw Objective-C runtime calls.
看看精彩的 F-Script 和 FSClass 可以做到这一点并且是开源的。 FSClass 定义了一个可以在运行时进行子类化的元类。
它确实可以通过使用 objc_allocateClassPair 和 objc_registerClassPair 来工作,但是还有很多其他事情正在进行(超出我的范围!)可能会有所帮助。
Have a look at the fabulous F-Script and FSClass which can do this and are open source. FSClass defines a meta-class that can be subclassed at runtime.
It does work by using objc_allocateClassPair and objc_registerClassPair but there is alot of other stuff going on (beyond me!) that would probably help.