編譯時和運行時的對象分別是什麼

就拿NSString * testObject = [[NSData alloc]init];作爲例子。編譯時和運行時的對象分別是什麼呢?


編譯時被當做NSString 的實例來處理,運行時其isa指向的是[NSData Class],故運行時該實例只能收到NSData的固有實例方法(或者自己寫的Category),如果對該實例發送諸如 testObject stringByAppendingString:@"哈哈哈" ,編譯時不會報錯只會給出黃色警告,但是運行時會直接崩潰,錯誤信息可能是

 

-[_NSZeroData stringByAppendingString:]: unrecognized selector sent to instance 0x8946440


故可以看出NSData 在運行時的真實類型是_NSZeroData(這裏用的NSData alloc init,這裏是個空的NSData,所以是ZeroData,不是說所有的)

如果對該實例發送諸如 testObject 
base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength:
這類消息,編譯器會直接給出紅色錯誤,無法運行,但其實這個實例是有這個方法的。


這裏如果改爲 id testObject=[[NSData alloc]init];

那麼發送NSString 的方法仍然會崩潰,發送NSData的實例方法則完全正常。並且兩種情況編譯器都不會再給出警告或錯誤。


這就是運行時語言的特點。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章