Create objective-c class instance by name?

Objective CReflection

Objective C Problem Overview


Is it possible to create an instance of a class by name? Something like:

NSString* className = @"Car";
id* p = [Magic createClassByName:className];
[p turnOnEngine];

I don't know if this is possible in objective-c but seems like it would be,

Objective C Solutions


Solution 1 - Objective C

id object = [[NSClassFromString(@"NameofClass") alloc] init];

Solution 2 - Objective C

NSClassFromString() runs the risk of mistyping the class name or otherwise using a class that doesn't exist. You won't find out until runtime if you make that error. Instead, if you use the built-in objective-c type of Class to create a variable, then the compiler will verify that the class exists.

For example, in your .h:

@property Class NameOfClass;

and then in your .m:

id object = [[NameOfClass alloc] init];

If you mistyped the class name or if it doesn't exist, you'll get an error at compile time. Also I think this is cleaner code.

Solution 3 - Objective C

If you are working with Objective-C without the NeXTstep (OS X, iOS, GNUstep etc) system or you just think this method is cleaner, then you could utilize the Objective-C language runtime library's API. Under Objective-C 2.0:

#import <objc/runtime.h>
//Declaration in the above named file
id objc_getClass(const char* name);
//Usage
id c = objc_getClass("Object");
[ [ c alloc ] free ];

Under the Objective-C (1.0 or unnamed version) you would utilize the following:

#import <objc/objc-api.h>
//Declaration within the above named file
Class objc_get_class( const char* name);
//Usage
Class cls = objc_get_class( "Test" );
id obj = class_create_instance( cls );
[ obj free ];

I haven't tested the 1.0 version, however I have used the 2.0 function in code that is now in production. I personally believe utilizing the 2.0 function is cleaner if available than the NS function as it consumes less space: the length of the name in bytes + 1 ( null terminator ) for the 2.0 API versus the sum of two pointers (isa, cstring), a size_t length (cstring_length), and the length of the string in bytes + 1 for the NeXTSTEP API.

Solution 4 - Objective C

@interface Magic : NSObject
+ (id)createInstanceOfClass:(Class)classe;
@end

@implementation Magic

+ (id)createInstanceOfClass:(Class)classe
{
	return [[classe alloc] init];
}

@end

Then to use it:

Car *car = [Magic createInstanceOfClass:[Car class]];
[car engineTurnOn];

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMarkView Question on Stackoverflow
Solution 1 - Objective CChris McCallView Answer on Stackoverflow
Solution 2 - Objective CSimon WoodsideView Answer on Stackoverflow
Solution 3 - Objective CMarkView Answer on Stackoverflow
Solution 4 - Objective CSkelaView Answer on Stackoverflow