开发者

Building Dynamic Classes in Objective C

开发者 https://www.devze.com 2022-12-22 19:26 出处:网络
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 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 regist开发者_开发知识库ered 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.


The reason that [[A alloc] init]; blows up is that the compiler has no clue what A means. The compiler never knows that A is even there.

Edit: Also, it looks like what you want is:

@interface A : NSObject {
  NSString *myString;
}

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

- (void)doItToIt;

@end

or perhaps

@interface NSString (MyPrivateExtension)

- (void)doItToIt;

@end


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.


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消