10

Which from the following is the correct way of obtaining the meta class?

Class myMetaClass = objc_getMetaClass("NSString");

Or:

Class myMetaClass = object_getClass([NSString class]);
  • Are they both any different?

  • As mentioned in another post that is linked by the first answerer here:

Please tell me why objc_getMetaClass(); would break in certain cases in detail.

  • The proper way to use those in different scenarios.
halfer
  • 19,824
  • 17
  • 99
  • 186
Unheilig
  • 16,196
  • 193
  • 68
  • 98
  • If you trace the calls in [the runtime library](http://opensource.apple.com/source/objc4/objc4-551.1/runtime/), they take different routes to get the info. `objc_getMetaClass()` is in objc-runtime.mm and `object_getClass()` is in objc-class.mm – jscs Jan 04 '14 at 20:29
  • @JoshCaswell Does that mean one is the proper way to use only for runtime and another is for the case used when runtime check is not necessary? – Unheilig Jan 06 '14 at 22:26
  • 1
    I'm not really sure, which is why I only posted a comment instead of an answer. I'd just guess that they were written at different times by people with different goals. I'm not sure one is necessarily "correct" or "better" for a client of the runtime. – jscs Jan 06 '14 at 22:38
  • @JoshCaswell Thanks nonetheless for reply.. – Unheilig Jan 06 '14 at 22:47
  • 1
    Sure thing. Sorry I couldn't be more helpful. – jscs Jan 06 '14 at 22:49

2 Answers2

4

Both functions are correct, but objc_getMetaClass("NSString") only works if NSString is registered with the objective C runtime. Which it almost always is if you want to get its metaclass.

But if you're creating a class using Class myClass = objc_allocateClassPair(superClass,"my_own_class",0) the situation is slightly different.

my_own_class isn't registered yet, so if you need to access the metaclass (in order to add class methods), you must use object_getClass(myClass). objc_getMetaClass("my_own_class") would return nil.

simple_code
  • 707
  • 9
  • 24
  • Thanks for response. So, if we use `objc_allocateClassPair(superClass,"my_own_class",0)`, how could we be sure when the class will be registered (or could we ourselves call a method to register it)? At which point is it usually registered with the runtime when we create a class by using `objc_allocateClassPair`? – Unheilig Jun 26 '15 at 11:45
  • The function to register it is `objc_registerClassPair(myClass)`. But After registering it, you can't change it. Which means, you can't add methods or properties or class methods after registering it. Basically, these functions are what you would use if you wanted to create classes at runtime. I haven't tried calling a method on a class that hasn't been registered, but I'm fairly sure it won't work. – simple_code Jun 30 '15 at 09:52
  • You might be able to edit a class after registering it. I haven't tried it. – simple_code Jun 30 '15 at 10:06
  • Thanks again for response; I am also pretty sure one cannot use a class unregistered. Would you mind telling me, however, what seems to serve as your doubt that one _might_ still be able to edit a class even after having registered it? I am just curious about that part, which seems to hinder slightly your assertion that a registered class cannot be further edited. Thank you. – Unheilig Jun 30 '15 at 10:38
  • I'm still learning to use the objective C runtime. I just tried to add a method to a meta-class I had already registered and it worked. I try to be careful to say anything without testing it first. – simple_code Jun 30 '15 at 11:05
  • Is it legitimate to do something like `Class myMetaClass = [[NSString class] class]` ? – Abhishek Vasisht Aug 31 '16 at 18:37
  • I tested that now, unfortunately `[[NSString class] class]` returns the same thing as `[NSString class]` as far as I can tell. – simple_code Sep 02 '16 at 07:36
2

The difference is, that the second function returns the object for the named class and the second first the object for the metaclass of the named class... :)

Both of them call the class handler callback if the class is not registered to check a second time. When you call the metaclass function you WILL get a return result.

...(However, every class definition must have a valid metaclass definition, and so the metaclass definition is always returned, whether it’s valid or not.) from: Objective-C Runtime Reference

I think your real question is: What is the difference between a class and a metaclass ? Please have a look at this excellent explanation: What is meta-class in objective-c

dehlen
  • 7,325
  • 4
  • 43
  • 71
  • I do know the difference, but I have seen different people using either of them to get a hold of the meta class. Some have suggested the 2nd one is more correct. I don't seem to recall what I saw the post. – Unheilig Jan 03 '14 at 12:02
  • you should go with your second approach, have a look at the comments on the accepted answer in this thread : http://stackoverflow.com/questions/20833144/in-objective-c-how-to-obtain-the-metaclass-object – dehlen Jan 03 '14 at 12:06
  • Yes, that's it. But why most of them tend to use the first approach (as in most questions / answers here in SO) and why is the 2nd approach more proper? Would like to know the details. – Unheilig Jan 03 '14 at 12:09
  • IMO it is because of the function name. But i can not give you more details why `objc_getMetaClass` could break, sorry :( – dehlen Jan 03 '14 at 12:10
  • It's ok. That's what I really would like to know. Thanks anyway. – Unheilig Jan 03 '14 at 12:12
  • 1
    i'll upvote you because it is interesting for me too... i only knew what to use not why – dehlen Jan 03 '14 at 12:13