1.id
在objc.h
中定義
typedef struct objc_class *Class;
typedef struct objc_object {
Class isa;
} *id;
從上面可以看出悉稠,id
的本質(zhì)
是struct objc_object結(jié)構(gòu)體指針
,可以指向任何OC對(duì)象。
注意:
這里說的是指向OC對(duì)象
粘都,像int、NSInteger
這些基本數(shù)據(jù)類型
是不
可以的,將id
指向int
會(huì)報(bào)錯(cuò)
OC中的基類除了NSObject之外刷袍,還有一個(gè)NSProxy虛類
翩隧。因此,id
相比NSObject *
指向的對(duì)象范圍要更廣
呻纹。
2.id
是動(dòng)態(tài)
數(shù)據(jù)類型堆生,而NSObject *
是靜態(tài)
數(shù)據(jù)類型,默認(rèn)情況下
所有的數(shù)據(jù)類型都是靜態(tài)
雷酪。
id
類型的實(shí)例在編譯
階段不會(huì)
做類型檢查淑仆,會(huì)在運(yùn)行時(shí)
確定,而類NSObject
的實(shí)例在編譯期要做編譯檢查
哥力,保證指針指向是其NSObject類或其子類蔗怠,當(dāng)然,實(shí)例的具體類型
也要在運(yùn)行時(shí)
才能確定,這也就是iOS三大特性之一的多肽
寞射。-
靜態(tài)類型
在編譯
時(shí)就知道變量的類型
最住,編譯時(shí)就知道變量的類型,在編譯
的時(shí)候就可以訪問對(duì)象的屬性
和方法
怠惶,如果訪問了不屬于
靜態(tài)類型的屬性
和方法
,那么編譯器就會(huì)報(bào)錯(cuò)
轧粟,而動(dòng)態(tài)數(shù)據(jù)類型
在編譯
的時(shí)候并不知道
變量的真實(shí)
類型策治,只有在運(yùn)行時(shí)的時(shí)候才知道它的真實(shí)類型,因此編譯時(shí)候如果訪問了不屬于
動(dòng)態(tài)類型的屬性
和方法
兰吟,編譯器不會(huì)
報(bào)錯(cuò)通惫,導(dǎo)致運(yùn)行
時(shí)的錯(cuò)誤,這也是動(dòng)態(tài)數(shù)據(jù)類型
的弊端
混蔼。
舉例如下:#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface People : NSObject -(void)eatFood; @end NS_ASSUME_NONNULL_END #import "People.h" @implementation People -(void)eatFood { NSLog(@"eatFood"); } @end #import "ViewController.h" #import "People.h" @interface ViewController () @end @implementation ViewController -(void)drinkWater { NSLog(@"drinkWater"); } - (void)viewDidLoad { [super viewDidLoad]; id test = [People new]; [test drinkWater]; // Do any additional setup after loading the view. } @end
從上面代碼我們不難看出履腋,drinkWater
方法并不是
id指針指向?qū)ο蟮?code>方法,調(diào)用了不是自己
的方法惭嚣,但是編譯
并沒有
報(bào)錯(cuò)遵湖,只有運(yùn)行時(shí)
才報(bào)錯(cuò)了。