2017-08-14 40 views
1

当我尝试编译下面的代码:为什么编译器不上[NSObject的初始化]返回错误

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

编译器让它生成并运行系统中的应用程序崩溃,但以下情况除外:

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 

据我所知,NSObject类有+ init方法,但是我没有在公共头文件中找到它,如果它是私有的,编译器应该告诉我们没有这样的方法。任何想法为什么编译器让我们建立这个代码?

+0

'+ initialize'或'-init'?我不知道'+ init'方法。 –

+0

@GerdK nope,+ init。尝试编译它,你会看到:) –

回答

6

类本身就是对象。每个类都有一个隐含的“元类”,而类是该元类的唯一实例。我们通常认为的“类Foo上的类方法”也是类meta-Foo上的一个实例方法。

在另一个怪癖中,类层次结构的根类的元类是根类本身的子类。这是meta-NSObject继承自NSObjectNSObject是本身的一个实例!

因此,NSObject的任何实例方法也是NSObject的类方法。也就是说,它可以在NSObject类本身上调用。这就是为什么编译器没有[NSObject init]的问题。

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

0

肯Thomases说,这种行为与元类的NSObject的。简而言之,我们可以在一个类的实例类上调用NSObject的所有方法。

对于NSObject层次结构中的所有实例,类和元类, 这意味着所有的NSObject实例方法都是有效的。对于 类和元类,所有的NSObject类方法也是有效的。

查看更多详情here。这diagram也很有用。

相关问题