NSObject常用方法superclass,[super superclass],isMemberOfClass,isKindOfClass,isEqual,clang
大家好,我是OB!
今天结合源码来看看NSObject常用方法
首先声明两个类,
Animal
,Dog
,继承关系如下
@interface Animal: NSObject
@interface Dog: Animal
1、 [Dog class]
和[dog class]
一样吗?
新手还在看,老手已经开始
NSLog
了。
结果是一样的。看看源码就清楚了,
+ (Class)class {return self;
}- (Class)class {return object_getClass(self);
}
这里要清楚三个概念,实例对象,类对象,元类对象。
我们创建的实例对象所拥有的实例方法,类方法,分别存储在类对象,元类对象。而 object_getClass
就是获取self
的类对象。
通过一个案例证实以上不是瞎说
struct ob_objc_class {Class isa;
};
int main(int argc, const char * argv[]) {@autoreleasepool {Dog *dog = [[Dog alloc] init];Class personClass = [dog class];struct ob_objc_class * personClass1 = (__bridge struct ob_objc_class *)(personClass);Class personMetaClass = object_getClass(personClass);}return 0;
}
打上断点,输入指令可以看到,
dog
的isa
指向了类对象dogClass
,而 类对象dogClass
的isa
指向了元类对象dogMetaClass
2、super
在Dog
的init中,下面打印什么?
- (instancetype)init{self = [super init];if (self) {NSLog(@"%@",[self class]);NSLog(@"%@",[super class]);NSLog(@"%@",[self superclass]);NSLog(@"%@",[super superclass]);}return self;
}
打印结果
Test_01[28917:2075877] DogTest_01[28917:2075877] DogTest_01[28917:2075877] AnimalTest_01[28917:2075877] Animal
这里是对
runtime
的objc_msgSend()
objc_msgSendSuper()
和super
关键字的理解
首先[self class]
和[super class]
编译过后会变成
objc_msgSend(self, sel_registerName("class"));
struct __rw_objc_super {self,class_getSuperclass(objc_getClass("Dog")),
};objc_msgSendSuper(__my__rw_objc_super,sel_registerName("class"));
最重要的是这两个方法的接受者,也就是方法调用者都是self
,
super
关键字,表示方法查找从父类开始,直接跳过了self
,但是接受者还是self
,所以当他们在NSObject
找到class
实现时,
//NSObject中class实现
- (Class)class {return object_getClass(self);
}
返回的都是Dog,
同理,superClass方法也是一样,只是方法查找的起始位置不一样,实现都是一样,
+ (Class)superclass {return self->superclass;
}
- (Class)superclass {return [self class]->superclass;
}
所以返回的都是Animal
3、isMemberOfClass
类A的类型 ?类B的类型,比较同一种类,不包含子父类
观察下面代码
NSLog(@"%d",[self isMemberOfClass:[Dog class]]); //1
NSLog(@"%d",[Dog isMemberOfClass:[Dog class]]); //0
为什么会出现这样的结果?先看看它的实现,可以看出这是只有当两个对象的类对象相等时,才能返回YES
+ (BOOL)isMemberOfClass:(Class)cls {return object_getClass((id)self) == cls;
}- (BOOL)isMemberOfClass:(Class)cls {return [self class] == cls;
}
注意类方法和实例方法中的
self
是不同的,类方法中的self
是类对象Dog
,而实例方法中的self
是dog
而 [Dog isMemberOfClass:[Dog class]]
中,相当于是object_getClass(Dog) == [Dog class];
而object_getClass(Dog)
其实是类对象的isa指向的元类对象dogMetaClass,所有不相等,
改成如下代码就可以了
[Dog isMemberOfClass:object_getClass([Dog class])] //1
4、isKindOfClass
类A是否是类B,或者是B的子类
NSLog(@"%d",[self isKindOfClass:[Dog class]]); //1
NSLog(@"%d",[Dog isKindOfClass:[Dog class]]); //0
NSLog(@"%d",[Dog isKindOfClass:object_getClass([Dog class])]); //1
和
isMemberOfClass
一样,只不过是多了个for循环,因为会去父类查找。
+ (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;
}
5、isEqual
比较两个对象是否完全
相等,比较内存地址
NSLog(@"%d",[self isEqual:[Dog class]]); // 0
NSLog(@"%d",[Dog isEqual:[Dog class]]); // 1
先看源码,就是完全比较两边是不是完全相等,
+ (BOOL)isEqual:(id)obj {return obj == (id)self;
}- (BOOL)isEqual:(id)obj {return obj == self;
}
所以[dog1 isEqual:dog2]
不相等,因为 dog1 != dog2
Dog *dog1 = [[Dog alloc] init];
Dog *dog2 = [[Dog alloc] init];
NSLog(@"%d", [dog1 isEqual:dog2]); //0
NSLog(@"%d", [[dog1 class] isEqual:[dog2 class]]); // 1
注意:如果是常量就不太一样了哦
NSString *s1 = @"werthjgfcdxsdfghgfdsdfg";
NSString *s2 = @"werthjgfcdxsdfghgfdsdfg";
NSLog(@"%d", [s1 isEqual:s2]); // 1
这里是相等的哦,因为s1和s2是常量,她们的内存地址一样哦。
今天先到这里!大家好我是OB!
对了,获取编译后的代码在终端指令
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc 需要编译的文件 -o 编译后的文件名
例如
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc /Users/OB/Desktop/Test_01/Test_01/main.m -o myMain.cpp
NSObject常用方法superclass,[super superclass],isMemberOfClass,isKindOfClass,isEqual,clang相关推荐
- NSObject常用方法 和反射
一. NSObject 常用方法 1. 判断一个对象是否属于某个类或子类 [对象 isKindOfClass:[类名]]; 返回 BOOL 值 2. isMemberOfClass判断对象是否属于某 ...
- NSObject的isa和superclass区别
这篇博客介绍的就是网上很流行的一张图关于isa和superclass的关系的解释! 温馨提示:如果你没有接触类的对象不了解的话,这篇博客有点费解,建议先看一下深入探究NSObject对象. 一.isa ...
- iOS runtime 底层详解、内部原理、场景应用
前言学:位域和共用体 一:isa指针--runtime之前的学习 1.1:苹果应用的按位或.按位与 二:类对象信息 2.1:类对象信息:rw_t 2.2:类对象信息:方法缓存(很关键) 2.2:类对象 ...
- 浅析class 、superclass、isMemberOfClass、isKindOfClass
经典图 抛出问题 BOOL res1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];BOOL res2 = [(id)[NSObjec ...
- 从源码理解runtime之super、superclass知识点
跟大家分享一道关于super和superclass的面试题,也是比较常见的面试题,请看下面的代码: 请问当前的4个结果输出是多少?我们平时写代码估计也不会这么写,面试官问你这些问题,主要是看你对sup ...
- self、 superclass 、 super的区别
self. superclass . super self : 当前方法的调用者 class:获取方法调用者的类对象 superclass:获取方法调用者的父类对象 super:不是一个指针,编译指示 ...
- super,class,superClass区别
-(void)test{//获取当前方法调用者的类NSLog(@"%@",[self class]); //当前方法调用者的父类 NSLog(@"%@",[se ...
- 【OC底层】OC对象本质,如 isa, super-class
Objective-C的本质 1.我们编写的Objective-C,底层现实都是C/C++,代码生成步骤如下: 2.在OC中的所有面向对象的实现,都是基于C/C++的数据结构实现的 3.将Object ...
- Exception in thread “main“ java.lang.ClassCastException: test.SuperClass cannot be cast to test.SubC
我创建的类是如下情况,编译过程中没有报错,但是当我执行该代码的时候,终端出现以下异常 Exception in thread "main" java.lang.ClassCastE ...
最新文章
- Linux终端设备详解
- freetype 安装
- C语言库函数(Q类字母)
- 超过12000个零件,钢琴就是一部复杂的机器
- w8服务器dns修改,Win8.1系统的DNS地址如何修改?修改win8.1系统DNS地址图文教程
- 深入探究VC —— 资源编译器rc.exe(3)
- lamp源码三层结构
- excel中的颜色代码(colorIndex)
- 小程序源码:全新独立后台月老办事处一元交友盲盒-多玩法安装简单
- 360校企培训:安全导论-试卷
- 高速公路测量计算CASIO程序全套
- win7电脑蓝屏没有修复计算机,Win7旗舰版系统电脑老是出现蓝屏的修复教程
- Django之DRF自定义action
- Mysql update from 使用
- C++ 学习(基础语法篇)
- 手机软件测试英语,手机软件测试,mobile phone software testing,音标,读音,翻译,英文例句,英语词典...
- LifeSmart云起局域网直接控制向往背景音乐
- CPU架构与指令集的关系
- 最新使用Mac自带的启动转换助理(Boot Camp)安装Windows10的详细方法教程-macbookpro 10.13.4
- 心目中的编程高手,经典计算机书籍作者介绍(部分,以后不定期更新)!