专栏首页老沙课堂super(二) 以及内存分布

super(二) 以及内存分布

一、练习

定义一个Person类

@interface Person : NSObject
@property (nonatomic, strong) NSString *age;
- (void)test;
@end

@implementation Person
- (void)test{
    NSLog(@"age = %@",self.age);
}

ViewController 继承自UIViewController

在ViewController 书写以下代码。问是否能编译通过,如果可以输出什么是什么?

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    id cls = [Person class];
    void * temp = &cls;
    [(__bridge id)temp test];
    
    
    Person *per = [[Person alloc] init];
    [per test];
    
}

运行结果

age = <ViewController: 0x7fb25241d9c0>
age = (null)

分析

1. [super viewDidLoad]

product -> Preform Action-> assemble 查看中间层代码

.loc	1 18 5 prologue_end     ## /Users/iOS/Desktop/Demo/Demo/ViewController.m:18:5
movq	-8(%rbp), %rsi
movq	%rsi, -32(%rbp)
movq	L_OBJC_CLASSLIST_SUP_REFS_$_(%rip), %rsi
movq	%rsi, -24(%rbp)
movq	L_OBJC_SELECTOR_REFERENCES_(%rip), %rsi
leaq	-32(%rbp), %rdi
callq	_objc_msgSendSuper2

其实super 底层实现的是_objc_msgSendSuper2 而不是上一篇文章的 _objc_msgSendSuper 两个还是有区别的。我们先看一下_objc_msgSendSuper传参

// rewrite-objc 结果
_objc_msgSendSuper(
	struct {
		id self
		Class superClass
  },@selector(viewDidLoad)
)
// 底层实现 汇编结果
  _objc_msgSendSuper2(
	struct {
		id receiver
		Class current_class
  },@selector(viewDidLoad)
)

通过assemble生成的中间代码可以看出调用的是_objc_msgSendSuper2 在源码中也有对_objc_msgSendSuper2的参数介绍

	ENTRY _objc_msgSendSuper2
	UNWIND _objc_msgSendSuper2, NoFrame

	ldp	p0, p16, [x0]		// p0 = real receiver, p16 = class
	ldr	p16, [x16, #SUPERCLASS]	// p16 = class->superclass
	CacheLookup NORMAL

	END_ENTRY _objc_msgSendSuper2

从源码中 可以看到 传入参数为第一个为接收者(self) 第二个参数为 [current class]

ldr	p16, [x16, #SUPERCLASS]	// p16 = class->superclass

在上面这句代码中 获取到当前class 的superclass

2.viewDidLoad中的内存分配

我们先看图下面区域

蓝色区域为person的实例变量。per指向person实例变量

而我们的对象方法存储在class中,所以通过指针找到per ->isa -> class ->方法列表 ->具体方法

我们再看图上面区域

蓝色区域为cls变量 temp指向cls cls指向person class

从图中我们可以看出,两个在内存结构几乎一致。

我们知道 c中是通过地址与指针找到对象。可以触发person的对象方法

既然是地址寻找。那当我们调用age属性的时候,正常走的是person实例变量的地址。而在temp中,这个地址为

self,所以temp中调用的age为viewcontroller 因为他们在相同的内存位置。

二、从源码的角度看isMemberOfClass和isKindOfClass

+ (BOOL)isMemberOfClass:(Class)cls {
  // 当类传进来的时候 获取的是mate-class
    return object_getClass((id)self) == cls;
}

- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

+ (BOOL)isKindOfClass:(Class)cls {
    for (Class tcls = object_getClass((id)self); tcls; tcls = tcls->superclass) {
				// 循环遍历父类 直到nil 或者相等
        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;
}

结论

当类方法object_getClass(self) == mate-class

  • isMemberOfClass 当前对象的class是等于传进来的class
  • isKindOfClass 是否为传进来类的类或者子类

本文分享自微信公众号 - 老沙课堂(gh_f73a6b772d4f),作者:rui4u

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-08-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 消息转发及super

    **消息转发的时候。由于oc的底层原理是消息机制,所以可以添加c语言函数等 **

    老沙
  • NSProxy 设计消息转发

    继承于NSProxy的类 找实现方法的时候 只会找当前类是否实现 而不找super,如果没找到直接进入消息动态解析,以及消息转发机制。比继承NSObject的类...

    老沙
  • isa详解(一)isa结构

    为什么要用union以及位运算呢。因为在计算机中为二进制。位运算是最快速的计算方式 union C++ 中的共用体。顾名思义 就是在union 中 公用一个内存...

    老沙
  • 【python刷题】并查集

    这里借用百度百科的一句话:并查集是一种树型的数据结构,用于处理一些不相交集合(disjoint sets)的合并及查询问题。常常在使用中以森林来表示。假设现在有...

    西西嘛呦
  • 最全总结!聊聊 Python 发送邮件的几种方式

    我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本、富文本、HTML 等格式的邮件

    AirPython
  • 最全总结!聊聊 Python 发送邮件的几种方式

    我们都知道 Python内置了对 SMTP 的支持,可以发送纯文本、富文本、HTML 等格式的邮件

    刘早起
  • 就这?我也能做!俄罗斯ACM-ICPC区域赛原题

    今天选择的是上周codeforces的ACM专场,这一场是俄罗斯ACM-ICPC的一场区域赛。对于acm感兴趣的同学可以尝试一下这套题,我感觉难度不是很大。这次...

    TechFlow-承志
  • 一起来学GOF23种设计模式

    从今天开始,资源君带大家来学习Java中的23种设计模式。首先我给大家简单介绍一下这23种设计模式:

    Python进击者
  • SaaS 企业收入评判标准将于 2017 年发生重大改变

    T客汇官网:tikehui.com 译文 | 张苏月 ? 原先一直推行的 SaaS 公司收入认证标准在 2017 年将要发生重大改变,其中对创业公司的影响颇为明...

    人称T客
  • Spark源码之Standalone模式下master持久化引擎讲解

    Spark源码之Standalone模式下master持久化引擎讲解 Standalone 模式下Master为了保证故障恢复,会持久化一些重要的数据,来避免m...

    Spark学习技巧

扫码关注云+社区

领取腾讯云代金券