OC对象的分类
- 实例对象(instance对象)
- 类对象(class对象)
- 元类对象(meta-class对象)
instance 对象
- 通过类
alloc出来的对象 - 每次
alloc都会产生新的instance对象(内存不相同) instance对象存储的信息- isa 指针
- 其他成员变量
class 对象
- 是创建对象的蓝图,描述了所创建的对象共同的属性和方法(made in 维基百科)
- 类在内存中只有一份,每个类在内存中都有且只有一个
class对象 class对象在内存中存储的信息- isa 指针
- superclass 指针
- 类的对象方法 && 协议
- 类的属性 && 成员变量信息
- 。。。
meta-class
` Class metaClass = object_getClass([NSObject class]);`
metaclss是NSObject的meta-class对象meta-class在内存中只有一份,每个类都有且只有一个meta-class对象meta-class也是类,与class的对象结构一样,但是内部的数据不一样(用途不同)meta-clas包括:- isa指针
- superclass
- 类方法
- 。。。
提问:object_getClass 与 objc_getClass的区别
Class object_getClass(id obj)
{
if (obj) return obj->getIsa();
else return Nil;
}
- object_getClass : 传入的是可以是任意对象(id类型),返回的是类 or 元类
- 如果传入
instance对象,返回class - 如果传入
class, 返回的是meta-class对象 - 如果传入的是
meta-class,返回的是root-meta-class对象
- 如果传入
Class objc_getClass(const char *aClassName)
{
if (!aClassName) return Nil;
// NO unconnected, YES class handler
return look_up_class(aClassName, NO, YES);
}
- 传入的是类名字符串,返回的是该类名对应的类
- 不能返回元类
(图片来自于 http://www.sealiesoftware.com/blog/archive/2009/04/14/objc_explain_Classes_and_metaclasses.html)
看懂这张图 - 就等价于看懂
isa&&superclass了
探究流程:
@interface MNSuperclass : NSObject
- (void)superclassInstanceMethod;
+ (void)superClassMethod;
@end
@implementation MNSuperclass
- (void)superclassInstanceMethod{
NSLog(@"superclass-InstanceMethod - %p",self);
}
+ (void)superClassMethod{
NSLog(@"+ superClass-classMethod- %p",self);
}
@end
@interface MNSubclass : MNSuperclass
- (void)subclassInstanceMethod;
@end
@implementation MNSubclass
- (void)subclassInstanceMethod{
NSLog(@"subclassInstanceMethod- %p",self);
}
@end
问: 子类调用父类的对象方法,执行的流程是如何的?
MNSubclass *subclass = [[MNSubclass alloc]init];
[subclass superclassInstanceMethod];
- 思路:
subclass调用对象方法,对象方法存在class中- 第一步,先找到
subclass对象,通过isa指针,找到其对应的MNSubclass类 - 看
MNSubclass是否有superclassInstanceMethod方法的实现,发现没有,MNSubclass沿着superclass指针找到他的父类 -MNSuperclass - 此时,
MNSuperclass中找到superclassInstanceMethod的实现,调用它,整个流程结束
[MNSubclass superClassMethod];
问: 子类调用父类的类方法,执行的流程是如何的?
- 思路:
- 类方法存在
meta-class中 - 第一步,找到对应的
MNSubclass,沿着isa指针,找到其对应的meta-class - 看
MNSubclass的meta-class中是否有superClassMethod方法的实现,发现没有,沿着superclass指针找到MNSuperclass的meta-class - 发现
MNSuperclass的meta-class有superClassMethod方法实现,调用,流程结束
- 类方法存在
图中比较难理解的一根线
探究 : 元类对象的superclass 指针是否指向 rootclass
- 分析:
meta-class对象存储的是类方法,class存储的是 对象方法- 从面向对象的角度来讲,一个类调用一个类方法,不应该最后调用到 对象方法
- 这里的
Root class就是NSObject, 要给NSObject添加方法就要用到分类 - 验证
NSObject的对象方法是否会被调用
//"NSObject+MNTest"类的声明 && 实现
@interface NSObject (MNTest)
+ (void)checkSuperclass;
@end
@implementation NSObject (MNTest)
+ (void)checkSuperclass{
NSLog(@"+NSObject checkSuperclass - %p",self);
}
@end
//main函数中调用
int main(int argc, char * argv[]) {
@autoreleasepool
{
[MNSubclass checkSuperclass];
NSLog(@"MNSubclass = %p",[MNSubclass class]);
}
return 0;
}
--------------------------------------------------------
控制台输出:
+NSObject checkSuperclass - 0x105817040
InterView-obj-isa-class[36303:7016608] MNSubclass = 0x105817040
- 发现,调用
checkSuperclass类方法的,是MNSubclass类- 这时候要验证上面那条
meta-class指向root-class的线, 这里的root-class即等于NSObjectroot-class中只存对象方法,这里,只要验证,NSObject中同名的类方法实现取消,变成同名的对象方法测试,即可得出结论- 声明的还是
+ (void)checkSuperclass,实现的方法用- (void)checkSuperclass对象方法替换
@interface NSObject (MNTest)
+ (void)checkSuperclass;
@end
@implementation NSObject (MNTest)
//+ (void)checkSuperclass{
// NSLog(@"+NSObject checkSuperclass - %p",self);
//}
- (void)checkSuperclass{
NSLog(@"-NSObject checkSuperclass - %p",self);
}
@end
//main函数中调用
int main(int argc, char * argv[]) {
@autoreleasepool
{
[MNSubclass checkSuperclass];
NSLog(@"MNSubclass = %p",[MNSubclass class]);
}
return 0;
}
--------------------------------------------------------
控制台输出:
-NSObject checkSuperclass - 0x101239040
InterView-obj-isa-class[36391:7022301] MNSubclass = 0x101239040
发现 - 调用的还是类方法 + (void)checkSuperclass ,但是最终实现的,却是对象方法 - (void)checkSuperclass
- 原因:
[MNSubclass checkSuperclass]其实本质上,调用的是发送消息方法,函数类似是objc_msgsend([MNSubclass class], @selector(checkSuperclass))- 这里的
@selector(checkSuperclass)并未说明是 类方法 or 对象方法 - 所以最终走流程图的话,
root-meta-class通过isa找到了root-class(NSObject), NSObject类不是元类,存储的是对象方法,所以 最终调用了NSObject -checkSuperclass这个对象方法
叮叮叮!循循循序渐进之面试题叒来了!!
@implementation MNSubclass
- (void)compareSelfWithSuperclass{
NSLog(@"self class = %@",[self class]);
NSLog(@"super class = %@",[super class]);
}
@end
调用:
MNSubclass *subclass = [[MNSubclass alloc]init];
[subclass subclassInstanceMethod];
- 问:
[self class]&&[super class]分别输出什么
@protocol NSObject
- (Class)class OBJC_SWIFT_UNAVAILABLE("use 'type(of: anObject)' instead");
- 思路:
class方法 是NSObject的一个对象方法,对方方法存在class中- 第一步,先找到
subclass对象,通过isa指针,找到其对应的MNSubclass类 - 看
MNSubclass是否有class方法的实现,发现没有,MNSubclass沿着superclass指针找到他的父类 -MNSuperclass - 查询
MNSuperclass中是否有class方法的实现,发现没有,MNSuperclass沿着superclass指针找到他的父类 -NSObject - 最终在
NSObject中找到class的实现 - 而调用方都是都是当前对象,所以最后输出都是 -
MNSubclass
验证:
NSLog(@"self class = %@",[self class]);
NSLog(@"super class = %@",[super class]);
----------------------------------------------------------------------
控制台输出:
InterView-obj-isa-class[36796:7048007] self class = MNSubclass
InterView-obj-isa-class[36796:7048007] super class = MNSubclass
感谢小码哥 的精彩演出,文章中如果有说错的地方,欢迎提出,一起学习~
友情客串: