19

Why does NSClassFromString return nil ? As per the definition it has to return class name. How should I take care to rectify this problem? I need to instantiate a class from string and call the method, which is in the class, using the instance created.

This is how my code looks like:

id myclass = [[NSClassFromString(@"Class_from_String") alloc] init];
[myclass method_from_class];

But the method_from_class function is not being called, control is not going into it. And my code is error free. Any idea how to solve this in Objective-C?

JOM
  • 8,139
  • 6
  • 78
  • 111
suse
  • 10,503
  • 23
  • 79
  • 113

7 Answers7

40

If you are trying to instantiate a class from a static library, you must add the "-ObjC" flag to the "Other Linker Flags" build setting.

m.kocikowski
  • 5,422
  • 2
  • 23
  • 9
31

The Documentation for the function says:

Return Value The class object named by aClassName, or nil if no class by that name is currently loaded. If aClassName is nil, returns nil.

An example of how this should be properly used is as follows:

Class dictionaryClass = NSClassFromString(@"NSMutableDictionary");
id object = [[dictionaryClass alloc] init];
[object setObject:@"Foo" forKey:@"Bar"];
Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • But the value in the string @"Class_from_String" has the value of the class name. because i've printed it just above ,before instantiating the class from string.Then how come it is taking as nil? – suse Feb 09 '10 at 06:16
  • hey 1've written 3rd line as: ***[object TestMethod];*** TestMethod is the method in same class, but stil the control is not going into the method defination. – suse Feb 09 '10 at 06:24
  • wat should i do. plz tel me some alternative. – suse Feb 09 '10 at 06:25
  • hi Dave.. do u have any idea, for alternative methos for NSClassFromString in Objective-C?My main purpose is to create an instance of class from string and to call a method using the instance created. – suse Feb 09 '10 at 06:34
  • 7
    @suse: Either your string isn't getting loaded correctly or _there is no class with that name known to the runtime,_ in which case you have to load it first. – Georg Schölly Feb 09 '10 at 06:39
  • @GeorgSchölly What could cause a class not to be loaded to the runtime? I'm having the same issue. – SpacyRicochet Dec 10 '12 at 16:38
  • 1
    @SpacyRicochet: Open a new question where you describe why you think your class should get loaded. Then we might be able to figure out why it doesn't work. – Georg Schölly Dec 10 '12 at 16:59
  • @Dave: In my opinion, when no class can be loaded with a given name, return value should be `Nil` (`(Class)0` - literal null value for classes), not `nil` (`(id)0` - literal null value for objects). Is the documentation not precise here or am I missing something? – matm Apr 02 '13 at 14:37
  • @delirus they're the same thing, so it doesn't really matter. `Nil` may be more semantically correct, but in the end it's all just `0`. – Dave DeLong Apr 02 '13 at 16:45
  • @Dave: semantical correctness was my only concern. Thanks for feedback. – matm Apr 02 '13 at 17:10
  • 2
    Interestingly enough, I came upon this post again due to another issue. And again, @GeorgSchölly's comment helped! Add `-ObjC` to the linker flags did the trick. – SpacyRicochet Apr 03 '14 at 13:49
4

It is possible that your class is not getting linked if this is the only reference to it.

I had a factory method to instantiate various types of subclass. The factory had a switch statement that went to the appropriate subclass and alloc'd and init'ed it. I noticed that all of the alloc/init statements were exactly the same, except for the name of the class. So I was able to eliminate the entire switch block using the NSClassFromString() function.

I ran into the same problem - the return was nil. This was because the class was not used elsewhere in the program, so it wasn't getting linked, so it could not be found at runtime.

You can solve this by including the following statement:

[MyClass class];

That defeats the whole purpose of what I was trying to accomplish, but it might be all you need.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
Al Smith
  • 49
  • 1
4

This happened to me when I add an external file to the Xcode project. Adding the .m file to Build Phases > Compile Sources solve the problem.

Quang Vĩnh Hà
  • 494
  • 3
  • 8
2

You also need to make sure the class you are trying to instantiate is included in the project. If you added it later, you made need to click the checkbox next to the Target you are building.

  • This answer worked for me. I added the new class while a different target was selected. I had to select: Target > Build Phases > Compile Sources > '+' to get the class _really_ added to the project. – David Manpearl Sep 12 '13 at 04:19
1

Why not decomposing all these calls ? This way, you can check the values between the calls:

Class myclass = NSClassFromString(@"Class_from_String");
id obj = [[myclass alloc] init];
[obj method_from_class];

By the way, is method_from_class an instance method or a class method ? If it is the later, then you can directly call method_from_class on the myclass value:

[myclass method_from_class];
Laurent Etiemble
  • 27,111
  • 5
  • 56
  • 81
  • "By the way, is method_from_class an instance method or a class method ?" Well, if it wasn't an instance method, his code should crash. – newacct Dec 18 '12 at 18:59
0

I also saw an oddity where adding the standard singleton code espoused by apple prevented the class from being loaded. The code was working as expected, then I added the singleton, and suddenly the NSClassFromString started returning nil. Commenting out the singleton code resulted in the NSClassFromString resolving the class correctly. I don't understand the interaction, but I think the singleton static var was somehow getting mangled to hide the class name...?

software evolved
  • 4,314
  • 35
  • 45