Objective-c Defining Class Runtime

Is it possible to define classes at runtime in objective-c?
For instance. Am I getting an XML file that defines an object and creates it and uses it at runtime?

+4
source share
3 answers

Yes, check this piece of code, I created a class here using only C methods and one protocol definition (for simplicity when making calls) ...

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, " i@ :"); 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; } 

Using:

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

Yes; quite possible. For more information, see the Objective-C Runtime Programming Guide for (including related manuals and documents).

As Justin said, this route is extremely atypical. If you download XML data, it almost always means that XML should have a well-defined structure - a strict DTD or schema - and thus you will be much better off with a disciplined, well-defined data model compiled into your application (via Core Data or direct implementation) with which you load the XML. This makes it easier to verify and will be much simpler.

The holy grail of โ€œfree-form consumptionโ€ is often seductive, but along this path lies madness and many tales of grief.

+5
source

yes, you can use objc runtime to create a type, define methods and store it - all this at runtime ... it's very unusual for that.

the interfaces you use are in the objc/runtime.h , and the calls you objc_allocateClassPair , class_addMethod , class_addIvar , etc. Obviously, you need to do a little work to create the class and its location, selector, etc. from the XML description. So yes, maybe, but it's not free.

+2
source

Source: https://habr.com/ru/post/1387076/


All Articles