「OC」源码学习——对象的底层探索

iOS底层原理探索—OC对象的本质 在探索OC对象的本质之前,我们要明白Objective-C的代码,底层的实现都是C/C++代码。 而OC中的对象、类则是基于C/C++的结构体来实现的。 我们可以通过将创建好的OC文件,转化成C++文件来看一下OC对象的底层结构。 OC代码转换成C++ 通过命令行将OC的main.m文件转换成C++,生成 main.cpp。 clang -rewrite-objc main.m -o ma... 阅读详情

「OC」源码学习——对象的底层探索

前言

上次我们说到了源码里面的调用顺序,现在我们继续了解我们上一篇文章没有讲完的关于对象的内容函数,完整了解对象的产生对于isa赋值以及内存申请的内容

函数内容

先把_objc_rootAllocWithZone函数的内容先贴上来

static ALWAYS_INLINE id
_class_createInstance(Class cls, size_t extraBytes,
                      int construct_flags = OBJECT_CONSTRUCT_NONE,
                      bool cxxConstruct = true,
                      size_t *outAllocatedSize = nil)
{
    ASSERT(cls->isRealized());//断言确保类已加载并完成内存布局(即 "realized" 状态)

    bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor(); //查看父类是否存在C++的析构函数
    bool hasCxxDtor = cls->hasCxxDtor();//查看是否存在C++的析构函数
    bool fast = cls->canAllocNonpointer();//是否支持指针优化
    size_t size;

    size = cls->instanceSize(extraBytes);//计算所需要的字节数
    if (outAllocatedSize) *outAllocatedSize = size;//返回计算的字节数

    id obj = objc::malloc_instance(size, cls);//根据类对象申请对应的内存
    if (slowpath(!obj)) {
        if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
            return _objc_callBadAllocHandler(cls);
        }
        return nil;
    }

    if (fast) {
        obj->initInstanceIsa(cls, hasCxxDtor);//如果是优化的isa指针先进入进行判断再进入initIsa
    } else {
        // Use raw pointer isa on the assumption that they might be
        // doing something weird with the zone or RR.
        obj->initIsa(cls);
    }

    if (fastpath(!hasCxxCtor)) {
        return obj;//没有析构函数就可以直接返回了
    }

    construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;//添加一个flag
    return object_cxxConstructFromClass(obj, cls, construct_flags);
}

我们来看看instanceSize这个函数究竟实现了什么,按照instanceSize->fastInstanceSize->align16,依次步入,我们可以看到一下内容

static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

这个程序就是一个16字节对齐的算法,先抛开这个算法,若是由我们来设计这个算法我们的思路是什么呢?最简单的就是

(x + 15) / 16 * 16

当然很快我们就意识到了,使用乘法和除法运算的效率和位运算相比实在太低了,正好16是2的4次方,位运算一样的解决啊

(x + 15) >> 4 << 4

OK现在设计完了我们在来看看苹果设计的代码

(x + 15) & ~15

~有按位取反的意思通过按位与操作,将低 4 位(二进制 1111)清零,得到最近的 16 的倍数。用size(15)是为了兼容32位和64机型,因为size_t 是无符号整数类型,其位数由平台决定(32 位系统为 4 字节,64 位系统为 8 字节)。当 x是 size_t 类型时,size_t(15) 确保运算中的右操作数(15)与左操作数(x)类型一致,避免隐式转换带来的风险

内存内容探究

GGObject *obj = [GGObject alloc];
NSLog(@"%lu", sizeof(obj));
NSLog(@"%lu", class_getInstanceSize(obj.class));
NSLog(@"%lu", malloc_size((__bridge const void*)(obj)));

根据这个内容我们可以看到自定义类对应的大小

image-20250424205643745

当我们的类被编译了之后,底层会类编译成 isa + 成员变量,所以在给类的实例分配内存的话这个内存块存储的就是 isa + 成员变量的值。

内存对齐

学过C语言我们都知道,结构体是有内存对齐这个概念的,当然不同的排列所实现的内存对齐是不同的,例如

struct Mystruct1{
    char a;     //1字节
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
}Mystruct1;

struct Mystruct2{
    double b;   //8字节
    int c;      //4字节
    short d;    //2字节
    char a;     //1字节
}Mystruct2;

//计算 结构体占用的内存大小
NSLog(@"%lu-%lu",sizeof(Mystruct1),sizeof(Mystruct2));// 打印:24 - 16

结构体安排的顺序会关系到结构体内存的大小,我们知道OC之中的对象其实就是由结构体构成的,那我们来探究一下不同的属性对对象的内存是否有影响呢

内存重排

对象的本质 = isa + 成员变量的值。

#import <Foundation/Foundation.h>
@interface MyPerson : NSObject
// isa 8字节
@property (nonatomic, copy) NSString *name; // 8字节
@property (nonatomic, copy) NSString *hobby; // 8字节
@property (nonatomic, assign) int age; // 4字节
@property (nonatomic, assign) double height; // 8字节
@property (nonatomic, assign) short number; // 2字节
@end

一共38字节,16字节内存对齐得到总的字节数为48字节,在探究内存问题之前,先学几个lldb命令

lldb指令:
  p   输出10进制
  p/x 输出16进制
  p/0 输出8进制
  p/t 输出2进制
  p/f 输出浮点数
         
  x   输出地址
  x/4gx  输出4个字节地址
  x/6gx  输出6个字节地址

现在我们用lldb进行调试

 MyPerson *p = [GGObject alloc];
  p.name = @"bb";
  p.hobby = @"吃吃睡睡喝喝";
  p.height = 1.80;
  p.age = 26;
  p.number = 123;

其实尝试着将类之中的属性内容,打印出来可以看到,无论属性怎么排列,这个MyPerson类age和number这两个属性永远会排在一起,这个就是编译器的内存优化,对属性进行重排

image-20250425194336343

我们看到在类的内部,我们的属性会通过重新排列获得最小内存,接下来我们看看能能不能重排父类的属性和子类属性吧

image-20250425200345352

还是可以看到子类属性并不会跟父类属性合并

@interface JCTestObject : NSObject
{
    @public
    int count;// 若count在此处,为JCTestSubObject实例实际需要40字节,系统为实例分配48字节
    NSObject *obj1;
    NSObject *obj2;
//    int count; // 若count在此处,为JCTestSubObject实例实际需要32字节,系统为实例分配32字节
    
}
@end
@interface JCTestSubObject : JCTestObject
{
    @public
    int count2;
}

isa走向

之前学习过关于isa指针的部分内容,

img

结论:

类的实例isa --> 类对象;
类对象isa --> 元类对象;
元类对象isa --> 根元类对象;
根元类对象isa --> 根元类对象自己。

objc_class 与 `objc_object

objc_object 是所有 Objective-C 对象的底层结构体,其定义如下

struct objc_object {
    isa_t isa;  // 指向类对象或元类的指针
};

objc_class 是类的底层结构体,类对象(如 [LGPerson class])和元类(metaclass)均为此类型。其继承自 objc_object,定义如下:

struct objc_class : objc_object {
    Class superclass;          // 父类指针
    cache_t cache;             // 方法缓存(哈希表)
    class_data_bits_t bits;    // 指向类信息(如方法列表、属性等)
};

1

img

class_getClassMethod和class_getInstanceMethod

先定义模版类

@interface JCObject : NSObject
{
    int _sum;
}
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *hobby;
@property (nonatomic, assign) int age;
@property (nonatomic, assign) double height;
@property (nonatomic, assign) short number;
- (void)speak;
- (void)sayHello;
+ (void)walk;
@end

@implementation JCObject

- (void)speak {
    NSLog(@"%s", __func__);
}
+ (void)walk {
    NSLog(@"%s", __func__);
}

-(void) sayHello {
    NSLog(@"%s", __func__);
}

在完成两个函数

void jcInstanceMethod_classToMetaclass(Class pClass){
    
    const char *className = class_getName(pClass);
    Class metaClass = objc_getMetaClass(className);
    
    Method method1 = class_getInstanceMethod(pClass, @selector(speak));
    Method method2 = class_getInstanceMethod(metaClass, @selector(speak));

    Method method3 = class_getInstanceMethod(pClass, @selector(walk));
    Method method4 = class_getInstanceMethod(metaClass, @selector(walk));
    
    NSLog(@"%s - %p-%p-%p-%p",__func__,method1,method2,method3,method4);
}

void jcClassMethod_classToMetaclass(Class pClass){
    
    const char *className = class_getName(pClass);
    Class metaClass = objc_getMetaClass(className);
    
    Method method1 = class_getClassMethod(pClass, @selector(speak));
    Method method2 = class_getClassMethod(metaClass, @selector(speak));

    Method method3 = class_getClassMethod(pClass, @selector(walk));
    Method method4 = class_getClassMethod(metaClass, @selector(walk));
    
    NSLog(@"%s-%p-%p-%p-%p",__func__,method1,method2,method3,method4);
}



//main函数
JCObject *person = [JCObject alloc];
Class pClass = object_getClass(person);
jcObjc_copyMethodList(pClass);
jcInstanceMethod_classToMetaclass(pClass);
jcClassMethod_classToMetaclass(pClass);

得到的结果

image-20250502230010829

jcInstanceMethod_classToMetaclass

要了解jcInstanceMethod_classToMetaclass之中的内容就要从理解class_getInstanceMethod开始,顾名思义class_getInstanceMethod这个方法,主要是用于获取实例方法,如果在传入的类或者类的父类中没有找到指定的实例方法,则返回NULL。从实例方法存储在类中,类方法存储在元类中可以得知,JCObject的方法列表打印结果只有sayHello方法

jcClassMethod_classToMetaclass

需要先了解class_getClassMethod这个方法,看该方法的源码实现,可以得出class_getClassMethod的实现是获取类的类方法,其本质就是获取元类的实例方法,最终还是会走到class_getInstanceMethod

//获取类方法
Method class_getClassMethod(Class cls, SEL sel)
{
    if (!cls  ||  !sel) return nil;

    return class_getInstanceMethod(cls->getMeta(), sel);
}

⬇️
//获取元类
//在getMeta源码中,如果判断出cls是元类,那么就不会再继续往下递归查找,会直接返回this,其目的是为了防止元类的无限递归查找
Class getMeta() {
    if (isMetaClass()) return (Class)this;
    else return this->ISA();
}

img

所以我们再来看看结果

对于speak方法存在于类对象之中,而walk方法存在于元类对象之中,所以使用class_getInstanceMethod可以在类对象之中找到speak方法,而在元类对象之中找到walk的类方法

而对于class_getClassMethod来说如果不是元类会先找到元类,然后再在元类之中查找类方法

iskindOfClass & isMemberOfClass

  • iskindOfClass & isMemberOfClass 类方法调用
//-----使用 iskindOfClass & isMemberOfClass 类方法
BOOL re1 = [(id)[NSObject class] isKindOfClass:[NSObject class]];       //
BOOL re2 = [(id)[NSObject class] isMemberOfClass:[NSObject class]];     //
BOOL re3 = [(id)[LGPerson class] isKindOfClass:[LGPerson class]];       //
BOOL re4 = [(id)[LGPerson class] isMemberOfClass:[LGPerson class]];     //
NSLog(@" re1 :%hhd\n re2 :%hhd\n re3 :%hhd\n re4 :%hhd\n",re1,re2,re3,re4);
  • iskindOfClass & isMemberOfClass 实例方法调用
//------iskindOfClass & isMemberOfClass 实例方法
BOOL re5 = [(id)[NSObject alloc] isKindOfClass:[NSObject class]];       //
BOOL re6 = [(id)[NSObject alloc] isMemberOfClass:[NSObject class]];     //
BOOL re7 = [(id)[LGPerson alloc] isKindOfClass:[LGPerson class]];       //
BOOL re8 = [(id)[LGPerson alloc] isMemberOfClass:[LGPerson class]];     //
NSLog(@" re5 :%hhd\n re6 :%hhd\n re7 :%hhd\n re8 :%hhd\n",re5,re6,re7,re8);

img

  • isKindOfClass
    检查对象是否属于指定类或其继承链中的任意父类。例如,若对象是 Person 类的子类实例(如 Student),则 [student isKindOfClass:[Person class]] 返回 YES
//--isKindOfClass---类方法、对象方法
//+ isKindOfClass:第一次比较是 获取类的元类 与 传入类对比,再次之后的对比是获取上次结果的父类 与 传入 类进行对比
+ (BOOL)isKindOfClass:(Class)cls {
    // 获取类的元类 vs 传入类
    // 根元类 vs 传入类
    // 根类 vs 传入类
    // 举例:LGPerson vs 元类 (根元类) (NSObject)
    for (Class tcls = self->ISA(); tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

//- isKindOfClass:第一次是获取对象类 与 传入类对比,如果不相等,后续对比是继续获取上次 类的父类 与传入类进行对比
- (BOOL)isKindOfClass:(Class)cls {
/*
获取对象的类 vs 传入的类 
父类 vs 传入的类
根类 vs 传入的类
nil vs 传入的类
*/
    for (Class tcls = [self class]; tcls; tcls = tcls->superclass) {
        if (tcls == cls) return YES;
    }
    return NO;
}

  • isMemberOfClass
    严格检查对象是否直接属于指定类,不包含继承链。例如,Student 实例调用 isMemberOfClass:[Person class] 会返回 NO,因为其直接类是 Student 而非 Person
//-----类方法
//+ isMemberOfClass : 获取类的元类,与 传入类对比
+ (BOOL)isMemberOfClass:(Class)cls {
    return self->ISA() == cls;
}
//-----实例方法
//- isMemberOfClass : 获取对象的类,与 传入类对比
- (BOOL)isMemberOfClass:(Class)cls {
    return [self class] == cls;
}

参考文章

iOS-底层原理 09:类 & isa 经典面试题分析

指导初学者使用Anaconda运行GitHub上One - DM项目的步骤 指导初学者使用Anaconda运行GitHub上One - DM项目的步骤。 阅读详情

相关推荐

安卓设备通过USB串口与STM32单片机通讯之一

这里写自定义目录标题欢迎使用Markdown编辑器`在这里插入代码片`新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器在这里插入代码片 你好下Markdown的基本语法知识。 新的改变 我们对

JGB联合商务组的博客 7244

ios开发小知识3

1、最简单关闭软键盘的方法 [view endEditing:YES];暂时总结出这些,后续会慢慢增加有点乱,实在是文笔不好,请见谅九十九条啊,我慢慢积累,一年估计还是能写到的吧//以下转自cc,http://www.cocoachina.com/bbs/read.php?tid=105689&page=1(一)关于UITableView1.任意设置Cell选中状态的背景色:UIVi...

weixin_30553065的博客 187

BurpSuite实战:5分钟搞定DVWA的CSRF漏洞测试(附详细截图)

本文详细介绍了如何使用BurpSuite在DVWA靶场中进行CSRF漏洞测试,包括环境配置、攻击原理剖析、分步攻击演示及企业级防御方案。通过实战案例,帮助读者深入理解CSRF漏洞的危害与防护措施,提升Web应用安全防护能力。

weixin_30879169的博客 492

OC经典代码

代码块 NSString *str=@"AAsadfadsfAABBBBB"; int arr[100]={}; for (int i=0; i<[str length]; i++) { arr[[str characterAtIndex:i ]-'A']++; } NSString *string=@"";

sinat_30777759的博客 764

LPDDR5/5X BG mode,8B mode和16B mode

LPDDR5/5X 器件,协议上支持多个bank架构可静态配置;配置在MR3:模式说明协议要求速率要求BLBG模式每CH 4BG, 4BALPDDR5/5X>3200MbpsBL16 & 328B模式每CH 8BALPDDR5任何速率BL3216B模式每CH 16BALPDDR5/5X<=3200MbpsBL16 & 32。

hemlok的博客 8858

模拟IC版图DRC实战:手把手教你搞定MIM电容天线错误和ESD.10g违例

本文深入解析模拟IC版图中的MIM电容天线错误和ESD.10g违例问题,提供从错误解码到实战修复的完整指南。通过电路图修改、版图优化和验证闭环等步骤,帮助工程师高效解决DRC错误,特别适用于ADC等精密模拟电路设计。文章还分享了高级排错技巧和预防性设计策略,大幅提升流片成功率。

weixin_27697385的博客 293

OC---IOS开发入门学习(一)

​ objactice-c简称obj-c或者OC。是基于 C 语言的、面向对象的编程语言。他将C语言中复杂繁琐的语法封装的更为简单。代码源文件通常以 .m 扩展名命名(c/c++为.c/.cpp)。m为message代表OC中的消息机制​用于开发 iOS 和 macOS 应用程序。OC完全兼容C语言。类的定义写在源文件中,主要分为两个部分1.类的声明@inteface 类名 :父类名 // NSObject是根类//属性写这里/*方法声明写这里方法声明语法:无参数:- (返回值类型)方法名;

yb941693493的博客 3582

通过JLink下载实现工控MCU批量烧录实战案例

利用JLink下载工具实现高效稳定的工控MCU批量烧录,提升产线效率。案例详细解析了脚本配置与自动化流程,突出jlink下载的可靠性和可扩展性,适用于大规模嵌入式部署场景。

weixin_30205153的博客 811

OC基础学习重要小知识点总结

1、首先,什么是Objective-C?   Objective-C是一门基于C语言的面向对象语言,C语言的基础上,增加了一层最小的面向对象语法,完全兼容c语言,它在现代计算机的主要作用于Mac OS X作为桌面语言以及作用于iPhone OS(亦称:iOS)。它原是NeXT

why_not_的专栏 2667

从JTAG到AS模式:一文搞懂EP4CE10E22C8N所有配置引脚(MSEL, nCONFIG, DATA0)的用法

本文深入解析EP4CE10E22C8N FPGA的配置引脚(MSEL, nCONFIG, DATA0)在不同模式下的使用方法,特别关注从JTAG到AS模式的切换要点。通过详细的配置模式对比、状态机分析和PCB布局建议,帮助开发者避免常见陷阱,提升FPGA配置成功率。

weixin_33713350的博客 319

基于BP神经网络PID控制的电机转速控制器设计复现

摘要:本文提出了一种基于BP神经网络PID控制的永磁同步电机转速控制方法,通过MATLAB/Simulink平台实现了算法复现。系统采用三层BP神经网络在线调整PID参数,包含输入层(误差、误差变化率、误差积分)、5节点隐含层和输出层(Kp、Ki、Kd)。仿真结果表明,相比传统PID控制,该方案具有更快的响应速度(上升时间减少约40%)、更小的超调量(降低约60%)和更强的抗干扰能力,在电动汽车电机驱动等复杂工况下表现优异。文中详细给出了PMSM数学模型建立、BP网络设计、权值更新算法及Simulink仿真

max500600的博客 306

OC基础代码

1.函数调用 不带参数 startedBlock(); 带参数 NSLog(@"decrypted string: %@", str); CGRectMake(0,0,0,0); 2.传递消息 不带参数 [obj method]; 带一个参数: [counter increase:1]; - (void) setColorToRed:

u013029811的专栏 452

反应堆设计:基于MATLAB的反应堆仿真和分析,包括反应堆稳态分析、反应堆动态分析和反应堆安全分析 介绍

反应堆设计是利用计算机技术对核反应堆进行设计和模拟,以获得安全、高效、经济的核能发电系统。它是核能领域的重要组成部分,在电力生产、核医学、科学研究等领域有着广泛的应用。

走向CTO的路上... 1112

「OC」源码学习——关联属性再探索

在寒假学习小蓝书的时候就已经接触过了关联属性,现在在学习源码的过程之中,在进行复习巩固以及深入学习iOS-底层原理 19:类扩展 与 关联对象 底层原理探索iOS 关联属性底层探索。

aa2002aa的博客 882

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

「OC」源码学习——KVO底层原理探究

之前在学习回调传值的时候,就对KVO进行了学习,接下来我们来继续进一步学习KVO之中的相关内容Block 回调的调用位置1. 定义 KVO 核心类与模型@end@end@end@end@end// JCKVO.m#import。

aa2002aa的博客 1180

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

OC底层学习-对象的本质

OC学习-对象的本质1. OC对象的本质1.1结构的内存对齐1.2 怎么把OC类通过终端转换成C++文件1.3 查看源码1.4面试题:一个NSObject的对象占多少内存?1.5实时查看内存数据1.6 常用的LLDB指令1.7 示例-验证-结论2 .Instance对象2.1 instance对象2.2 Class对象2.3 meta_class元类对象2.4 isa指针2.5 .面试题2.5.1 对象的isa指针指向哪里2.5.1 OC的类信息存放在哪里?2.5 答疑 1. OC对象的本质 OC代码经过

yong_19930826的博客 880

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

【iOS】类与对象底层探索

这里我们需要注意一个问题:为何图中的以及中的类信息打印的结果都是CJLPerson?0x00000001000081e8是perosn对象的isa指针地址,他&后得到的结果是创建person的类CJLPerson。而0x00000001000081c0是isa中获取的类信息所指的类的isa的指针地址,就是CJLPerson类的类的isa指针地址,在Apple中我们将其简称为元类。故而,我们可以了解到两个打印都是CJLPerson的根本原因是元类导致的。

2301_79847748的博客 1685

「OC」源码学习——锁

在多线程编程中,锁的作用是,防止多个线程同时修改同一数据导致的数据混乱、逻辑错误甚至程序崩溃。我们可以发现售出的票基本都是乱序的,也就是说访问的时候,不同线程访问同个内容出现了问题,这时候就需要锁来规范顺序。

aa2002aa的博客 905

iOS开发 搞懂runtime系列文章(一)OC对象的底层结构

iOS开发中,runtime库作为底层基础设施,发挥着重要的作用,可以说,runtime赋予了OC这门语言灵魂,让OC这门语言变得动态化和极具灵活性,让开发者可以对代码本身进行编程,俗称元编程。万丈高楼平地起,只有明白了runtime底层的原理,才能在软件开发中游刃有余,避免隐秘的错误的发生。iOS开发中的很多知识点都和runtime息息相关,比如内存管理,弱引用,关联对象,分类,方法调用,继承等等。

a296776627的博客 1279

IOS底层探索(一)OC对象内存分析

IOS底层探索(一)OC对象内存分析11.1 OC对象占用内存原理11.1.1 初始OC对象占用内存11.1.1.1 查看内存具体内容方法11.1.1.2 查看属性占用内存情况 11.1 OC对象占用内存原理 OC对象 最少占用 16 个字节内存. 当对象中包含属性, 会按属性占用内存开辟空间. 每一行 16 个字节中, 剩余内存如果可以放下剩余其中一个属性 (参考倒数第二张图) , 则会在...

kyl282889543的博客 478

[iOS]-OC对象底层探索

OC对象底层探索浅谈

m0_52192682的博客 804

OC底层原理之NSObject

本系列主要是看完MJ的OC底层原理课程所写的总结,希望自己能加深对iOS底层的了解。 NSObject的本质 NSObject的底层实现就是一个结构体 ,而且只带有一个Class类型的成员变量isa @interface NSObject{ Class isa; } struct NSObject_IMPL{ Class isa; } 复制代码OC对象的本质 分析Objec...

weixin_33826609的博客 240

IOS底层原理 - 1.OC对象本质

综述: objective-c 的代码(clang -rewrite-objc mian.m -o mian.cpp)最终转成c/c++代码,然后转成汇编代码,最终以机器码执行;那么OC的对象最终在转成c、C++代码后是什么呢?其实C/C++中都能容纳不同类型的数据结构就是结构体,所以Objective-C 的对象/类主要是基于结构体实现 注:生成arm64架构的cpp文件 1:一个oc对象的内存...

HOSTEN的博客 3409

OC底层探索(二) :源码探索的三种方式

源码探索的三种方法 符号断点直接跟流程 通过按住control+step into 汇编跟流程 1. 符号断点 以alloc为例: 选择断点Symbolic Breakpoint 符号断点中输入 alloc 在alloc断点处跟进 在执行alloc时,打开alloc符号断点, 然后进入下面页面,我们就会发现alloc 的源码libobjc.A.dylib库 2. 通过按住control+step into 在alloc处打一个断点, 当断点执行到alloc时,按住contro

正在注销账号的博客 304

IOS底层原理(一)OC对象alloc原理

IOS底层原理(一)OC对象alloc原理

kyl282889543的博客 481

iOS 类与对象底层原理

对象的isa是指向类,类其实也是一个对象,可以叫做类对象.类对象的位域3指向平果定义的元类元类是系统给的,他的定义和创建都是由编译器玩测的,这个过程中,类的归属来自于元类元类是类对象的类,每一个类都有独一无二的元类来存储类方法的相国信息元类本身是没有名字的,只是因为类与之关联,所以直接采用了类的一个名字这里我们继续用调试来观察所有的对象都是由objc_object继承过来的所有的对象,类,元类都有isa属性.以objc_object为模板创建的对象,都有isa。

qq_73106050的博客 1391
上一篇: 「OC」源码学习——objc_class的bits成员探究
下一篇: 「OC」源码学习——cache_t的原理探究
小鹿撞出了脑震荡
博客等级 码龄3年 1107粉丝 97原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值