学习
实践
活动
工具
TVP
写文章
专栏首页Jacklin攻城狮「类与对象」揭秘本质的第一步

「类与对象」揭秘本质的第一步

0-1-0-1

Objective-C本身是一种高级语言,底层都是由C/C++实现。

若想了解Objective-C一些API具体实现以及一些对象真实的数据结构等,就需要将Objective-C语言转化成C/C++语言。

OC代码的转换过程

OC语言转化成C/C++的相关命令

  • 需要使用的命令:
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp
  • 使用Xcode自带的命令:xcrun
  • 选择指定编译平台(SDK):iphoneos,查看所有的支持的SDK,执行命令xcodebuild -sdks,结果如下:

查看支持的SDK

  • 选择指定架构,可以选择模拟器(i386)、x86_64、64bit(arm64)、32bit(armv7),由于IPhone属于arm64架构所以添加参数:-arch arm64
  • 默认使用的是Clang编译器:需要使用clang相关命令
  • 若想支持ARC,需要添加-fobjc-arc
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc  main.m -o main.cpp
  • 需要指定运行时的系统版本,可以添加-fobjc-runtime=ios-8.0.0
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m -o main.cpp
  • 需要指定框架:-framework,比如-framework UIKIt
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc -fobjc-arc -fobjc-runtime=ios-8.0.0 main.m -o main.cpp -framework Foundation

...

关于xcrun命令使用掌握上述几种,就足以开发使用,其他用法还有很多就不在这一一介绍了。

最终使用的命令:

xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m -o main.cpp

项目实践

创建一个实例项目并将项目中的main.m转换成main.cpp文件,具体展示如下:

code.gif

文件目录相关截图如下:

生成后的代码

main.m相关代码:

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

main.cpp相关代码:

struct AppDelegate_IMPL {
    struct UIResponder_IMPL UIResponder_IVARS;
};
/* @end */


int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        appDelegateClassName = NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class")));
    }
    return UIApplicationMain(argc, argv, __null, appDelegateClassName);
}
static struct IMAGE_INFO { unsigned version; unsigned flag; } _OBJC_IMAGE_INFO = { 0, 2 };

我想,大家刚开始做iOS开发的时候,心中总会有一个疑问:

创建的对象都是继承自`NSObject`类,那`NSObject`类底层数据结构是什么呢?

今天,就用上面的编译命令,一探NSObject类真实面目!

1、在main.m文件中创建一个新的NSObject对象:

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
        
        // 创建一个NSObject对象
        NSObject *obj = [[NSObject alloc] init];
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}

2、clang编译后:

struct AppDelegate_IMPL {
    struct UIResponder_IMPL UIResponder_IVARS;
};

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        appDelegateClassName = NSStringFromClass(((Class (*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("AppDelegate"), sel_registerName("class")));

        NSObject *obj = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc")), sel_registerName("init"));

    }
    return UIApplicationMain(argc, argv, __null, appDelegateClassName);
}

3、查看NSObject在Objective-C语言中的声明:

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

精简后:
@interface NSObject <NSObject> {
    Class isa;
}

那么它对应的真实数据结构是什么呢?

于是在刚刚编译后的main.cpp文件中,搜索NSObject关键字,经过筛选比对,最后找到一个与上述NSObject结构相似的结构,如下所示:

struct NSObject_IMPL {
    Class isa;
};

IMPL一般是Implementation缩写,从而从侧面验证了NSObject底层数据结构是结构体

今天就到这了。

本文参与 腾讯云自媒体分享计划 ,欢迎热爱写作的你一起参与!
本文分享自作者个人站点/博客:https://www.jianshu.com/u/ef991f6d241c复制
如有侵权,请联系 cloudcommunity@tencent.com 删除。
登录 后参与评论
0 条评论

相关文章

  • 「类与对象」揭秘本质的第一步

    若想了解Objective-C一些API具体实现以及一些对象真实的数据结构等,就需要将Objective-C语言转化成C/C++语言。

    Jacklin
  • 类的本质-类对象

    今天整理了下自己电脑里的一些碎片笔记,时间有限只整理了这篇文章——类的本质,大家可以进行参考。

    VV木公子
  • 类对象 与 类的对象

  • 函数式编程与面向对象编程[5]:编程的本质函数式编程与面向对象编程[5]:编程的本质编程的本质

    函数式程序员在洞察问题方面会遵循一个奇特的路线。他们首先会问一些似有禅机的问题。例如,在设计一个交互式程序时,他们会问:什么是交互?在实现 基于元胞自动机的生命...

    一个会写诗的程序员
  • iOS底层—OC对象的本质与isa

    我们已经学习了对象的初始化、内存对齐等内容。这篇文章将深入学习探究对象的本质、对isa进行分析。

    CC老师
  • 面向对象与面向过程的本质的区别

    如果你很想搞明白面向对象是什么,面向过程是什么,或者说二者之间的区别是什么,那么就花费一点时间来研读一下这篇博客,你一定会有很大的收获的!

    全栈程序员站长
  • 「类与对象」NSObject对象的分类

    刚开始接触Objective-C语言的时候,看到说到的最多的概念就是「类和对象」。最初的认识停留在把类实例化就变成对象了,天真认为只存在类与对象两种。

    Jacklin999
  • 类与对象」NSObject对象的分类

    刚开始接触Objective-C语言的时候,看到说到的最多的概念就是「类和对象」。

    Jacklin
  • 面向对象的基础类与对象

    我们回想一下,这几天我们完成一个需求的步骤:首先是搞清楚我们要做什么,然后在分析怎么做,最后我们再代码体现。一步一步去实现,而具体的每一步都需要我们去实现和操作...

    星哥玩云
  • 类与对象的绑定方法

    py3study
  • 类与对象,类的继承,类的派生,类的组合,多态

    在python中先有类再有对象,类和对象,你可以看成,类是把对象的相同特征和相同方法汇总再一起,再根据类来生成对象,这个对象具有类的特征与方法

    小小咸鱼YwY
  • Swift系列六 - 结构体与类的本质区别

    常见的Bool、Int、Double、String、Array、Dictionary等常见类型都是结构体。

    呆呆
  • PHP方法类与对象的区别

    不知道有人是否和作者一样,不是特别的能区分方法类和对象的区别呢。那么今天就用一个简单例子解释类和对象的区别。

    小唐同学.
  • Java---对象与类的封装

    谙忆
  • 类加载机制与对象的创建

    查找并加载类的二进制数据加载时类加载过程的第一个阶段,在加载阶段,虚拟机需要完成以下三件事情:

    leobhao
  • Python - 类中的对象与属性

    为为为什么
  • 面向对象(一)【“类与对象”的概念及特性】

    面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程范式,同时也是一种程序开发的抽象方针。在...

    用户1432189
  • java中类与对象的关系与区别

    参考博客:https://blog.csdn.net/scbiaosdo/article/details/79912037

    用户7886150
  • 谈谈我对面向对象以及类与对象的理解

    对于刚接触JAVA或者其他面向对象编程语言的朋友们来说,可能一开始都很难理解面向对象的概念以及类和对象的关系。笔者曾经带过一个短期培训班教授java入门基础,在...

    Java团长

扫码关注腾讯云开发者

领取腾讯云代金券