1.一个ObjectC对象中都有什么
NSString *hellow = @"hellow";
NSLog(@"%@",hellow);
在NSLog处打上断点
可以看到对象中有一个isa指针,这个指针指向了Class类型的_NSCFConstantString(其实是NSString的一个内部类,可以看做NSString),这个isa指针是一个什么东西?
@interface NSObject <NSObject> {
Class isa OBJC_ISA_AVAILABILITY;
}
NSObject的头文件中可以看到,isa指向一个Class对象。
2.Class 到底是个什么东西
typedef struct objc_class *Class;
objc_class又是什么?
struct objc_class {
Class isa OBJC_ISA_AVAILABILITY;
#if !__OBJC2__
Class super_class OBJC2_UNAVAILABLE;
const char *name OBJC2_UNAVAILABLE;
long version OBJC2_UNAVAILABLE;
long info OBJC2_UNAVAILABLE;
long instance_size OBJC2_UNAVAILABLE;
struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
struct objc_cache *cache OBJC2_UNAVAILABLE;
struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
#endif
} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */
可以看出Class其实是一个结构体。其中存储了类的元数据。
刚才的例子中hello这个NSString对象中的isa指针指向了NSString的Class(封装了NSString类的元数据)。
这个Class中存储了这个NSString对象的相关方法,属性,协议等信息。
而Class的定义中,第一个成员也是一个Class类型的isa,说明NSString的Class也是一个Objective-C对象。这个isa指向另外一个类,这个类叫做“元类”。
元类这个Class则存储了NSString的类方法等信息。
3.元类与元类之间存在跟类一致的继承关系。
4.类的继承关系的相关判断
- 判断一个对象是否属于一个特定的类
NSMutableDictionary *mDic = [NSMutableDictionary new];
[mDic isMemberOfClass:[NSDictionary class]]; //NO
[mDic isMemberOfClass:[NSMutableDictionary class]]; //YES
[mDic class] == [NSMutableDictionary class] //YES
最后==这种判断是因为每个类的class是单例模式,仅有一个这样的对象。但是并不推荐这样做,因为在对象的类实现了转发机制,并且把所有的转发都发给代理对象的时候,就判断不准确了。比如如下这种情况:
@interface MyProxy : NSProxy
@property (nonatomic,strong) id obj;
@end
@implementation MyProxy
- (Class)class{
return [self.obj class];
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel{
return [self.obj methodSignatureForSelector:sel];
}
- (void)forwardInvocation:(NSInvocation *)invocation{
[invocation invokeWithTarget:self.obj];
}
@end
//执行代码
id proxy = [MyProxy alloc];
((MyProxy *)proxy).obj = [[NSString alloc] init];
[proxy class] == [MyProxy class]; //NO
- 判断一个对象是否是一个类或者其子类
[mDic isKindOfClass:[NSMutableDictionary class]]; //YES
[mDic isKindOfClass:[NSDictionary class]]; //YES
[mDic isKindOfClass:[NSArray class]]; //NO