關於NSObject和運行時系統
類NSObject
OC作為一門動態編程語言,有很多動態的特性,OC不僅需要編譯環境,還需要一個運行時系統(runtime system)來執行編譯好的代碼。運行時系統扮演的角色類似於OC的操作系統,它負責獨立完成對象的生成,釋放時的內存管理等。
程序中無法直接使用運行時系統提供的功能。根類方法中提供了運行時系統的基本功能,繼承了NSObject的所有類都可以自由地使用運行時的功能,也就是說,根類相當於運行時系統的一個借口。
1.類和實例
NSObejct只有一個實例變量,就是Class類型的變量isa。isa用於標識實例對象屬於哪個類對象。isa用於標識實例對象屬於哪個類對象。因為isa決定著實例變量和類的關系,很重要,所以子類不可以修改isa的值。也不能直接通過訪問isa來查詢變量到底屬於哪個類,而要通過實例方法class來完成查詢。
NSObject的方法與其說是為自己定義的,不如說是為其子類和所有的實例對象而定義的。
-(Calss)class; 返回接受者所屬類的類對象。
+(Class)class;返回類對象
-(id)self;返回接受者自身。是一個無任何實際動作但很有的方法。
-(Bool)isMemberOfClass:(Class)aClass; 判斷消息接受者是不是參數aClass類的對象。
-(Bool)isKindOfClass:(Class)aClass判斷消息接受者是否是aClass嘞或者是aClass類的子類的實例。這個和isMemberOfClass的區別在於當消息的接受者是aClass的子類的實例時也會返回YES;
-(Bool)isSubclassOfClass:(Class)aClass;判斷消息接受者是不是參數aClass的子類或自身,如果是則返回YES
-(Class)superclass;返回消息接受者所在的父類的類對象;
+(Class)superclass;返回消息接受類的父類的類對象
2.實例對象的生成和釋放
+(id)alloc;
-(void)dealloc;釋放實例對象
-(oneway void)release;
-(id)retain;
-(id)autorelease;
-(NSUInterger)retainCount;
-(void)finalize;垃圾收集器在釋放接受者對象之前會執行該finalize方法。
上面congdealloc到retainCount都是手動引用計數管理內存時調用的方法,使用ARC時不可用,finalize僅供垃圾回收有效時使用。
3.初始化
-(id)init
-(void)initialize;被用於類的初始化,也就是對類中共同使用的變量進行初始化,這個方法會在類收到第一個消息之前被自動調用,不能手動調用,而且只會被調用一次。
+(id)new;new是alloc和init 的組合。
4.對象的比較
-(Bool)isEqual:(id)anObject; 消息的接收者如果和參數anObject相等就返回YES
-(NSUinteger)hash;在把對象放入容器等的時候,返回系統內部用的散列值。【散列值相等的兩個對象不一定相等,快速檢索系統中一般都有散列表,OC的Foundation框架中也有用於計算散列的函數。數據存放的位置是由數據本身計算出來的散列值來決定的。及時內容相同的情況下,如果算出來的散列值不同,數據存放的位置也是不同的】
5.對象的內容描述
+(NSString *)description;返回一個NSSTring類型的字符串,表示消息接受者所屬類的內容,通常都是這個類的類名。
-(NSString *)description;返回一個nsstring類型的字符串,表示消息接收者的實例對象的內容。通常是類名加id值,子類中也可以重新定義description的返回值。
6.關於消息發送機制
選擇器和SEL類型
程序中的方法名(選擇器)在編譯後會被一個內部標識符所替代,這個內部標識符所對應的數據類型就是SEL類型。
OC為了能夠在程序中操作編譯後的選擇器,定義了@selector()指令。通過使用@selector()指令就可以直接引用編譯後的選擇器。也可以生命SEL類型的變量。
選擇器不同的情況下編譯轉化後生成的SEL類型的值也不一定想不同,相同的選擇器所對應的SEL類型的值一定相同。