內省(Introspection)是面向對象語言和環境的一個強大特性,Objective-C和Cocoa在這個方面尤其的豐富。內省是對象揭示自己作為一個運行時對象的詳細信息的一種能力。這些詳細信息包括對象在繼承樹上的位置,對象是否遵循特定的協議,以及是否可以響應特定的消息。NSObject協議和類定義了很多內省方法,用于查詢運行時信息,以便根據對象的特征進行識別。
明智地使用內省可以使面向對象的程序更加高效和強壯。它有助于避免錯誤地進行消息派發、錯誤地假設對象相等、以及類似的問題。
iOS 中內省的幾個方法
- 判斷對象類型:
-(BOOL) isKindOfClass: 判斷是否是這個類或者這個類的子類的實例
-(BOOL) isMemberOfClass: 判斷是否是這個類的實例
+ (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
- (BOOL)isKindOfClass:(Class)cls {
for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
if (tcls == cls) return YES;
}
return NO;
}
+ (BOOL)isMemberOfClass:(Class)cls {
return object_getClass((id)self) == cls;
}
- (BOOL)isMemberOfClass:(Class)cls {
return [self class] == cls;
}
- 判斷對象or類是否有這個方法
-(BOOL) respondsToSelector: 判讀實例是否有這樣方法
+(BOOL) instancesRespondToSelector: 判斷類是否有這個方法
class方法和objc_getClass方法有什么區別
- object_getClass:獲得的是isa的指向,比如:實例對象的isa是類對象,類對象的isa是元類對象。
- self.class:當self是實例對象的時候,返回的是類對象,否則則返回自身。類方法class,返回的是self,所以當查找meta class時,需要對類對象調用object_getClass方法。
+ (Class)class {
return self;
}
- (Class)class {
return object_getClass(self);
}
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
inline Class
objc_object::getIsa()
{
if (isTaggedPointer()) {
uintptr_t slot = ((uintptr_t)this >> TAG_SLOT_SHIFT) & TAG_SLOT_MASK;
return objc_tag_classes[slot];
}
return ISA();
}
inline Class
objc_object::ISA()
{
assert(!isTaggedPointer());
return (Class)(isa.bits & ISA_MASK);
}
參考:
object_getClass(obj)與[obj class]的區別
iOS 中內省的幾個方法?class方法和objc_getClass方法有什么區別
Objective-C Runtime 入院第一天—— isa 和 Class