objc.h

2023-10-27

objc.h

头文件阅读

Class

Class在Runtime中的定义:

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

可以看到Class是一个objc_class类型的结构体指针。

也就是说OC的类,本质就是一个objc_class类型的结构体指针。

那objc_class是个什么样子的结构体呢?得找找objc_class的定义。

objc_class在runtime.h中:

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

objc_object

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};

/// A pointer to an instance of a class.
typedef struct objc_object *id;

这里定义了一个结构体objc_object。

这个结构体里有一个Class类型的指针isa。

objc_object这个结构体做什么用的?isa有什么作用?

SEL

/// An opaque type that represents a method selector.
typedef struct objc_selector *SEL;

SEL是一个objc_selector类型的结构体指针。

从现在的阅读来看,不查查其他资料我还真不知道这个SEL就是一个方法的标识,通过这个标识找到对应的方法。

SEL是selector的大写缩写。selector是一个方法选择器,这个在OC中经常使用到。

通过selector获取SEL:

SEL sel1 = @selector(method1);
NSLog(@"sel : %p", sel1);//打印SEL的地址

SEL可以看看,选择性摄取,我感觉里面说的有些是有点问题的。

IMP

/// A pointer to the function of a method implementation. 
#if !OBJC_OLD_DISPATCH_PROTOTYPES
typedef void (*IMP)(void /* id, SEL, ... */ ); 
#else
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull, ...); 
#endif

查了查资料OBJC_OLD_DISPATCH_PROTOTYPES这个宏是为了兼容LLVM这个编译器架构做的特殊处理。

两个方法,一个有返回值一个没有返回值。

这里定义了一个这样的函数,暂时我们不知道是做什么的,也不知道IMP是什么。

推荐阅读 看看就行了,有助于理解IMP。

一些函数定义

  • sel_getName
OBJC_EXPORT const char * _Nonnull sel_getName(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

这个sel_getName()函数返回值是一个const char 类型的,参数需要传一个SEL类型的。

举个没太有什么实际意义的例子:

//通过sel_getName函数获取方法名,并转化成字符串输出

NSString *name = [NSString stringWithCString:sel_getName(@selector(run)) encoding:NSUTF8StringEncoding];
NSLog(@"******** %@",name);
  • sel_registerName
OBJC_EXPORT SEL _Nonnull sel_registerName(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

这个函数返回一个SEL类型的参数,注册一个新的方法?

  • object_getClassName
OBJC_EXPORT const char * _Nonnull object_getClassName(id _Nullable obj)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

返回指定对象的类名

例如:

NSString *className = [NSString stringWithCString:object_getClassName(p) encoding:NSUTF8StringEncoding];
NSLog(@"p所属的类:%@",className);
  • sel_isMapped
OBJC_EXPORT BOOL sel_isMapped(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

返回一个BOLL类型的值,参数是一个SEL类型的。

这个方法是检测方法是否合法的吗?

BOOL isMapped = sel_isMapped(@selector(run));
NSLog(@"isMapped %d",isMapped);
BOOL isMapped1 = sel_isMapped(@selector(sayHello));
NSLog(@"isMapped %d",isMapped1);

试了试返回值总是1,这是怎么回事?

*sel_getUid

OBJC_EXPORT SEL _Nonnull sel_getUid(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);

返回值一个SEL类型的指针,传入参数是个const char类型的指针

char string[] = "run";
const char *run = string;
SEL sel = sel_getUid(run);
NSLog(@"%p",sel);//0x113046083

方法总结

//通过sel获取方法名
OBJC_EXPORT const char * _Nonnull sel_getName(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
   
    
//注册新方法??
OBJC_EXPORT SEL _Nonnull sel_registerName(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
   
    
//通过对象获取对象所属的类名
OBJC_EXPORT const char * _Nonnull object_getClassName(id _Nullable obj)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
    
    
//这个方法ARC下是禁止使用的
OBJC_EXPORT void * _Nullable object_getIndexedIvars(id _Nullable obj)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0)
    OBJC_ARC_UNAVAILABLE;


//??
OBJC_EXPORT BOOL sel_isMapped(SEL _Nonnull sel)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);


//获取方法的SEL指针地址的函数
OBJC_EXPORT SEL _Nonnull sel_getUid(const char * _Nonnull str)
    OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0, 2.0);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

objc.h 的相关文章

  • 在Java中,类上的静态方法有什么缺点吗?

    让我们假设在我的编码环境中已经强加了一条规则 或者经验法则 即类上不使用 修改或以其他方式需要任何实例变量来完成其工作的任何方法都将被设为静态 这样做是否有任何固有的编译时间 运行时间或任何其他缺点 已编辑以进一步澄清 我知道这个问题有点开
  • 混合运行时是可行的解决方案吗?

    在我的公司 我们最近从 VC9 切换到 VC10 我们迁移了我们的项目 但是负责人告诉我们 我们必须在我们的生产机器上保留一些用 VC9 编译的基本通用 DLL 一段时间 这些 DLL 使用自定义结构 其中一些包含std vector st
  • 我什么时候需要下载.Net core运行时?

    From this https dotnet microsoft com download sdk链接 我们可以下载Core SDK和Runtime 据我了解 SDK 包含运行时 但在什么情况下我应该下载 Net Core Runtime
  • 如何在运行时替换 Moose 对象的方法?

    是否可以在运行时替换 Moose 对象的方法 通过查看源代码Class MOP Method http search cpan org perldoc Class MOP Method which Moose Meta Method htt
  • PHP Yii:运行时数据库连接

    我想在运行时使用 Yii 连接到第二个数据库 数据库名称将来自用户登录后的数据库表 我在教程中看到我应该这样做 db2 Yii createComponent array class gt EMongoClient server gt mo
  • EF7 在运行时更改连接字符串

    在 EF 的早期版本中 我们能够更改 dbcontext 连接字符串 如下所示 context Database Connection ConnectionString the new connectionstring 我们如何使用 EF7
  • constexpr 函数何时在编译时进行求值?

    既然声明为 constexpr 的函数有可能在运行时被调用 那么编译器根据什么标准决定是在编译时还是在运行时计算它呢 template
  • 如何在运行时更改android中睡眠/定时器线程的延迟?

    我试图做的是每次计数器变为 5 的倍数时减少计时器延迟 但是 一旦代码进入 if 块 它就停止递增计时器 我不明白发生了什么事 这是代码 thread new Thread public void run try if count 5 0
  • 以编程方式添加项目引用

    基本上 在阅读了几个链接后 我尝试了上面的代码 foreach EnvDTE Project proj in soln Projects if proj Name BLL VSLangProj VSProject vsproj VSLang
  • 发送 cmdarray 供 exec 处理——hello world

    我不是发送一系列命令 hello world 到exec https docs oracle com javase 7 docs api java lang Runtime html exec 28java lang String 5B 5
  • 如何从java/或命令行使用/m“宏参数”打开word文档而不指定winword.exe路径

    我想做接下来的事情 String cmd cmd c c Program Files x86 Microsoft Office Office12 WINWORD exe mOpenPage c Navodilo doc Process pr
  • 如何在Java程序中检索环境变量的修改值(外部修改的)?

    是否可以在 Java 程序中检索环境变量的修改值 我尝试使用System getenv 但新的值并没有体现在程序中 场景是这样的 该程序检索环境变量的值 当程序仍在运行时 该变量的值可以从外部更改 甚至可以是手动过程 例如在 Windows
  • 在 O(n) 时间内运行的指数乘法算法?

    我正在读一本算法教科书 我被这个问题难住了 假设我们要计算值 x y 其中 x 和 y 为正数 分别具有 m 和 n 位的整数 解决该问题的一种方法是执行 y 1 乘以 x 你能给出一个仅使用 O n 乘法步骤的更有效的算法吗 这会是一个分
  • 应用程序启动时立即隐藏导航栏

    基于以下代码片段 我能够隐藏状态栏当应用程序启动时 但不是导航栏 由后退 主页和任务管理器按钮组成的栏 因为它隐藏了稍后在 MainActivity 的线程完成加载后 这是清单
  • Java - Runtime.getRuntime().exec() 发生了什么?

    我在 Java 中遇到 Runtime exec 问题 我的代码 String lol home pc example txt String b touch lol try Runtime getRuntime exec b catch E
  • GOMAXPROCS 默认值是多少?

    不设置同名环境变量时是否保证GOMAXPROCS设置为1 此代码显示的值 package main import runtime fmt func getGOMAXPROCS int return runtime GOMAXPROCS 0
  • Maven:无法在 OS X 上找到 java.lang 问题

    当我尝试时遇到以下问题mvn clean install显然它无法找到运行时 jar 但我需要做什么 错误日志 ERROR COMPILATION ERROR INFO ERROR Failure executing javac but c
  • 具有重复符号的 C++ 插件库上的段错误

    我有一个跨平台 C 应用程序 它分为多个共享库 并从插件共享库加载附加功能 插件库应该是自包含的并自行运行 无需了解或依赖于调用应用程序 其中一个插件包含从主应用程序复制的代码 因此包含与引擎中的符号名称重复的符号名称 是的 我知道这通常是
  • C# 用数组封送结构体

    假设我有一个类似于 public struct MyStruct public float a 我想用一些自定义数组大小实例化一个这样的结构 在本例中假设为 2 然后我将其封送到字节数组中 MyStruct s new MyStruct s
  • 在 Java 和 C 中在运行时调用名为“string”的方法

    我们如何调用名称为的方法string在运行时 谁能告诉我如何在 Java 和 C 中做到这一点 在java中可以通过反射api来完成 看一下Class getMethod String methodName Class parameterT

随机推荐

  • SV_POSITION VPOS 在像素着色器上是一的意思和作用

    SV POSITION 在顶点着色器上就是齐次裁剪空间的变换 作为顶点着色器的输出和个像素着色器的输入 但在像素着色器里就表示的是像素为单位的屏幕空间了
  • 算法和数据结构项目练习7-广度优先搜索(BFS)

    Breadth First Search 项目介绍 代码实现 项目介绍 本项目实现广度优先搜索算法 读取txt文件中第一行表示图中顶点数的单个整数N 读取txt文件中第二行开始是一对对的整数 每一对表示图中某条边两端的两个顶点 图是无向的
  • C++ Primer 学习笔记 第十四章 重载运算与类型转换

    C 允许我们自定义类类型之间的转换规则 重载的运算符是具有特殊名字的函数 它的名字由operator和运算符构成 重载的运算符函数参数数量与该运算符作用的运算对象的数量一样多 一元运算符有一个参数 二元运算符有两个参数 且二元运算符的左侧运
  • 利用VNC实现Windows远程访问Linux服务器小结

    一 vnc veiw访问在vmw虚拟机上的linux Linux服务器架设在VMware之上的虚拟机 那么可以直接使用VMware自带的vnc 而不用自己安装 只要在VMware的设置中将远程显示的选项打开 指定一个端口和密码就可以了 如下
  • 前端设计稿转代码现状,会不会失业?

    大厂技术 高级前端 Node进阶 点击上方 程序员成长指北 关注公众号 回复1 加入高级Node交流群 前言 前端近年来一直在尝试如何提高开发人员的效率 从最初的脚手架工具 组件库 持续集成体系 自动化测试 多端适配到现在的全面的低代码平台
  • C#中创建对象的几种方式

    一 使用new关键字 这个是我们使用最多的方式 创建简单 但是扩展性较差 二 使用工厂方法 工厂方法是一种设计模式 通过在类中定义静态方法来创建对象 把对象创建过程封装在方法内部 比如 using System namespace Simp
  • Python中学习器流水线Pipeline

    sklean提供的pipeline来将多个学习器组成流水线 通常流水线的形式为 将数据标准化的学习器 特征提取的学习器 执行预测的学习器 除了最后一个学习器之外 前面的所有学习器必须提供transform方法 该方法用于数据转化 例如 归一
  • 网络面试-ox09 http是如何维持用户的状态?

    http是无状态 无连接的特性 无连接 使用了keep alive 来处理 无状态 使用了Cookie Session 来维持 解决无状态的方案 2 种 基于Session实现的会话保持 lt 1 gt 在客户端第一次向服务器发送 HTTP
  • vbs整人小病毒2

    海螺 大家好 这是我第二次发文章 点个赞再走吧 Thanks 还有关注 好 直接上代码 Dim AutoRunProgram Set AutoRunProgram WScript CreateObject WScript shell Reg
  • 构建高并发高可用的电商平台架构大纲

    构建高并发高可用的电商平台架构大纲 参考 http blog csdn net yangbutao article details 12242441
  • 人工智能的常用十种算法

    1 决策树 根据一些 feature 进行分类 每个节点提一个问题 通过判断 将数据分为两类 再继续提问 这些问题是根据已有数据学习出来的 再投入新数据的时候 就可以根据这棵树上的问题 将数据划分到合适的叶子上 2 随机森林 视频 在源数据
  • SpringBoot 整合websocket 测试出错

    问题描述 javax websocket server ServerContainer not available 问题起因 一般情况下 使用 SpringBootTest后 Spring将加载所有被管理的bean 基本等同于启动了整个服务
  • 实现Callable接口

  • 【HarmonyOS】【DevEco Studio】ohpm安装失败该如何解决?

    关键词 HarmonyOS DevEco Studio ohpm安装失败 问题背景及解决方案 最近遇到很多DevEco Studio安装ohpm失败的问题 下面给大家介绍几种出现的问题以及解决方案 1 ohpm not set up 报错截
  • 测试用例--测试大纲(提纲)法

    测试大纲 提纲 法 一 应用场合 程序包含多个窗口 每个窗口有多个操作 这些操作之间有一定的关系 为了弄清楚窗口之间不同操作的联系 可以使用测试大纲法 常用于测1 软件的安装 删除程序2 界面之间的跳转关系等 二 测试大纲法的测试步骤 步骤
  • pread,pwrite,read,write区别

    pread pwrite include
  • tc命令——Linux基于IP进行流量限速

    https blog csdn net zhongbeida xue article details 54613750
  • NumPy学习笔记

    NumPy author 段浩 Created on Thu Nov 10 10 21 20 2022 Numpy的介绍 在数据分析和科学计算的领域 Numpy占据十分重要的地位 Numpy使得python具备了操作多维数组的功能 并且效率
  • GET和POST有什么区别?

    简要概括 1 GET提交的数据会放在URL之后 以 分割URL和传输数据 参数之间以 相连 参数值通常以 号赋值 而POST方法是把提交的数据放在HTTP包的Body中 2 GET提交的数据大小有限制 最多只能有1024字节 因为浏览器对U
  • objc.h

    文章目录 objc h 头文件阅读 Class objc object SEL IMP 一些函数定义 方法总结 objc h 头文件阅读 Class Class在Runtime中的定义 An opaque type that represe