Search code examples
objective-cxcodensobjectfoundation

Why compiler doesn't return error on [NSObject init]


When I try to compile the following code:

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        [NSObject init];
    }
    return 0;
}

compiler let it build and then the app crashes in runtime with the following exception:

2017-08-14 14:56:07.937859-0700 NSObjectInit[30512:11241814] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSObject<0x7fff9fd83140> init]: cannot init a class object.'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff818e32cb __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00007fff966f348d objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff8196517f +[NSObject(NSObject) init] + 127
    3   NSObjectInit                        0x0000000100000f2d main + 61
    4   libdyld.dylib                       0x00007fff96fd9235 start + 1
    5   ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

As I understand, there is +init method in NSObject class, but I didn't find it in public headers and if it is private, complier should tell us that there is no such method. Any ideas why compiler let us build this code?


Solution

  • Classes are themselves objects. There is an implicit "meta-class" for each class and the class is the one and only instance of that meta-class. What we normally think of as a "class method on class Foo" is also an instance method on class meta-Foo.

    In a further quirk, the meta-class of the root class of a class hierarchy is a subclass of the root class itself. That is meta-NSObject inherits from NSObject. The class NSObject is an instance of itself!

    So, any instance method of NSObject is also a class method of NSObject. That is, it can be invoked on the NSObject class itself. That's why the compiler doesn't have a problem with [NSObject init].

    http://sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html