2017-08-14 59 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也很有用。

相關問題