如何在 Objective-C 中编写调用 `super` 实现的 c 函数? [复制]

2024-03-09

我需要实现一个通用 C 函数,它将调用super的实现并返回值。我将在运行时将此函数注入到目标类中。目标选择器的参数数量可以是任意数量,并且只有在运行时才知道。

我实现了一个C函数,如下所示,但我不知道如何调用super带有变量参数列表的实现:

id forwardMessageToSuper (id self, SEL _cmd, ...) {

    // Is this `super` definition right?
    struct objc_super super = {
        self,
        [self superclass]
    };  

    // How can I pass the variable argument list (...) to super? 
    id result = objc_msgSendSuper(&super, _cmd, ...);

    return result;
}

另一个问题:如何以及何时使用objc_msgSendSuper_stret调用super的实施?


一种解决方案是用 super 的 IMP 调配方法的 IMP 并调用它,然后调配回来。

就是这样wax https://github.com/probablycorey/wax did it.

代码取自https://github.com/probouslycorey/wax/blob/master/lib/wax_instance.m https://github.com/probablycorey/wax/blob/master/lib/wax_instance.m

static int superMethodClosure(lua_State *L) {
    wax_instance_userdata *instanceUserdata = (wax_instance_userdata *)luaL_checkudata(L, 1, WAX_INSTANCE_METATABLE_NAME);
    const char *selectorName = luaL_checkstring(L, lua_upvalueindex(1));

    // If the only arg is 'self' and there is a selector with no args. USE IT!
    if (lua_gettop(L) == 1 && lua_isstring(L, lua_upvalueindex(2))) {
        selectorName = luaL_checkstring(L, lua_upvalueindex(2));
    }

    SEL selector = sel_getUid(selectorName);

    // Super Swizzle
    Method selfMethod = class_getInstanceMethod([instanceUserdata->instance class], selector);
    Method superMethod = class_getInstanceMethod(instanceUserdata->isSuper, selector);        

    if (superMethod && selfMethod != superMethod) { // Super's got what you're looking for
        IMP selfMethodImp = method_getImplementation(selfMethod);        
        IMP superMethodImp = method_getImplementation(superMethod);
        method_setImplementation(selfMethod, superMethodImp);

        methodClosure(L);

        method_setImplementation(selfMethod, selfMethodImp); // Swap back to self's original method
    }
    else {
        methodClosure(L);
    }

    return 1;
}

正如@JesseRusak 指出的,这不是线程安全的,所以你需要锁定它。递归调用也可能有问题。

for objc_msgSendSuper_stret你可以检查这个answer https://stackoverflow.com/a/8406105/642626

objc_super superstruct = {self, [SuperClass class]};
CGSize size = ((CGSize(*)(struct objc_super *, SEL, NSString*))objc_msgSendSuper_stret)(&superstruct , @selector(contentSize:), text);

也适用于这段代码

struct objc_super super = {
    self,
    [self superclass]
}; 

通常你不想使用[self superclass]因为它可能会导致无限循环。你可以尝试弄清楚当子类调用 super 时会发生什么。您需要以某种方式确保调用 super 不会再次调用此方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Objective-C 中编写调用 `super` 实现的 c 函数? [复制] 的相关文章

  • 主队列上的dispatch_sync 与dispatch_async

    请耐心等待 这需要一些解释 我有一个类似于下面的函数 上下文 aProject 是一个名为 LPProject 的核心数据实体 其数组名为 memberFiles 其中包含另一个名为 LPFile 的核心数据实体的实例 每个 LPFile
  • 如何在 iPhone 应用程序中播放来自服务器的视频 URL

    实际上 我通过使用从服务器获取一个网址XMLParser 我想在我的应用程序中播放这个视频网址 现在我使用了 MPMoviePlayerController 但它不起作用 请帮忙 XML解析器 m id loadXMLByURL NSStr
  • 理解@property装饰器和继承[重复]

    这个问题在这里已经有答案了 这里是 Python 3 以防万一它很重要 我试图正确理解如何实现继承 property使用 我已经搜索了 StackOverflow 并阅读了大约 20 个类似的问题 但无济于事 因为他们试图解决的问题略有不同
  • 错误:“消息回复时间太长”向设备手表套件 OS 2 发送消息

    从 Apple Watch 向设备发送消息时出现以下错误 错误域 WCErrorDomain代码 7012 消息回复时间太长 UserInfo NSLocalizedDescription 消息回复时间太长 NSLocalizedFailu
  • iPhone中的异步for循环

    for循环看起来像这样 我在视图中编写的确实加载了 因此加载此页面需要更多时间 for int i 3 i lt dataDict objectForKey rss objectForKey channel objectForKey ite
  • 如何检查 uiviewcontroller 是否存在于 uinavigationcontroller 堆栈中

    我有一个UINavigationController 我必须从 a 中弹出一个视图UINavigationController并将其替换为另一个视图 我们如何才能搜索到一个UIViewController对象并将其替换为另一个 当我打印时
  • 如何在操作表中添加日期选择器?

    IBAction showCatPicker if self catList nil self catList nil catList release self catList NSMutableArray alloc init self
  • iOS 8 UITableView 分隔符插入 0 不起作用

    我有一个应用程序 其中UITableView的分隔符插入设置为自定义值 右0 Left 0 这完美地适用于iOS 7 x 但是在iOS 8 0我看到分隔符插入设置为默认值15在右侧 即使在 xib 文件中它设置为0 它仍然显示不正确 我该如
  • 在 ios wifi 网络上查找对等点

    我试图弄清楚如何搜索登录到 wifi 网络且在特定端口上托管应用程序的其他设备 在不知道这些其他设备的地址甚至不知道它们托管的端口的情况下 如何检测它们的存在 一旦发现 我应该能够联系该设备并与其建立连接 最标准的 iOS方式 是使用Bon
  • 为什么我的 x 轴在 iPhone 上不显示核心图?

    编辑 我认为我的问题更好地表述为 我怎样才能有一个不从零开始的 Y 轴 看起来 x 轴总是放置在 y 0 处 但我希望 x 轴位于 y 轴上的某个正数 这是一张包含更多常规数据的图表 我只是希望将 x 轴放置在绘图的最小 y 值 大约 77
  • 这是 NSDateFormatter 风格 12 月 18 日星期五

    我想知道这个日期格式是什么Friday December 18th这也是标准的日期格式 或者我必须付出一些努力才能得到这个 Thanks 我不认为th可以通过格式化程序来实现 虽然你可以这样做 NSDate today NSDate dat
  • 为什么分割视图控制器必须始终是您创建的任何界面的根?

    在苹果的开发者指南中 他们指出 分割视图控制器必须始终是您创建的任何界面的根 see here http developer apple com library ios featuredarticles ViewControllerPGfo
  • 锁定时 AVAudioPlayer 在 iPhone 5 中不播放音频

    使用 AVAudioPlayer 我尝试在 iphone 播放器播放时播放声音 当设备锁定时也是如此 问题是 在 iPhone 4s ios 7 中 效果很好 但在带有 6 和 7 ios 的 iPhone 5 上没有任何反应 In the
  • Objective-C 字符串文字的预处理器宏值

    我在构建设置中定义了一个预处理器宏 FOO BAR 我想将该值转换为可以传递给方法的 Objective C 字符串文字 以下 define 不起作用 但它应该展示我想要实现的目标 define FOOLITERAL FOO want FO
  • Cocoa - 在另一个 xib 上显示 xib

    谁能告诉我如何 或指导我有关信息 在另一个 xib 笔尖 上显示 xib 笔尖 我希望如何放置它 以便我可以以编程方式将它移动到主笔尖 就像这样 这显然不起作用 void drawRect NSRect dirtyRect NSRect c
  • 如果部署目标 < 基础 sdk,如何检查是否使用了不可用的方法?

    我想知道当部署目标低于基础 SDK 时 您如何检查代码是否不调用不可用的方法 可以在 SDK 等于部署目标的设备上运行应用程序 但我搜索一种更 自动 的方式 任何想法 问候 昆汀 最简单的方法是使用 IPHONE OS VERSION MA
  • 多次显示admob插页式广告怎么办?

    我有一个小型游戏应用程序 它有一个故事板 里面创建了像开始菜单 游戏区域 分数这样的场景 我在其中添加了 admob 横幅视图和插页式广告 我的横幅视图工作正常 但我的插页式广告只能工作一次 我在 viewdidload 上加载插页式广告
  • 如何使用编译时间作为自动版本控制信息?

    当程序被编译以获得一种自动版本信息时 是否有任何常量或 pragma来获取时间和日期 DATE and TIME 是预定义的宏 将分别扩展到当前日期和时间
  • 使用 PHP 和 jSON 从 MySQL 获取 UIImage

    我正在开发一个小型新闻阅读器 它通过对 URL 执行 POST 请求来从网站检索信息 响应是一个带有未读新闻的 JSON 对象 例如 应用程序上的最新新闻的时间戳为 2013 03 01 当用户刷新表时 它会发布 domain com ap
  • 具有多个 sqlite 文件的核心数据

    如何将 Core Data 与多个 SQLite 文件一起使用 每个文件都包含相同的结构 但数据是从不同的位置检索的 我希望能够在运行时根据应用程序设置在这些 sqlite 文件之间切换 当然 只需指向持久存储协调器 NSPersisten

随机推荐

  • @Injectable(providedIn: 'root') 的语义?

    只是想确保我理解的语义 Injectable providedIn root 在 Angular 6 之前 如果我们从 NPM 导入包含服务的模块 我们会在应用程序模块中声明该模块 以便整个应用程序都可以访问该服务 像这样的事情 impor
  • 建立新的 Java 开发中心

    我正在建立一个 Java 开发商店 目前只是我自己作为唯一的开发人员 但希望随着业务的增长需要雇用其他人 显然 我希望将其设置正确 以便随着更多人的加入 他们可以立即提高工作效率 请帮助建议我想做的事情以及完成这些事情的工具 这是我认为我需
  • Django 模型继承 - 在查询中只需要父类的实例

    假设我有 2 个模型 一个是另一个的父模型 如何查询 Django 中所有不是餐厅的地点 Place objects all 将包括所有餐厅 对吗 我想将孩子排除在结果之外 谢谢你 class Place models Model name
  • 将多个不相邻列复制到数组

    我正在尝试将多个不相邻 不连续 的 Excel 列复制到数组中 但它不起作用 以下是我尝试过的 Public Function Test Dim sh As Worksheet Set sh Application Sheets MyWor
  • Response.End 之后关闭窗口

    例如我有一个表格ListView即处于编辑模式 发生了一些事情 导致列表视图正在使用的表不再可用 我只想在用户点击 保存 时能够关闭窗口 In Page Load 我检查桌子是否可用 如果没有 我打电话RegisterClientScrip
  • Visual Studio 设计器中的抽象 UserControl 继承

    abstract class CustomControl UserControl protected abstract int DoStuff class DetailControl CustomControl protected over
  • Django:如果用户是工作人员,如何排除表单字段?

    如果用户不是员工 如何排除表单字段 我尝试了这个 但没有成功 给出了一个错误 global name user is not defined class PostForm ModelForm class Meta model Photo e
  • API 来比较 AST? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有一个开源java api允许比较java源代码的两个抽象语法树 我想看看两个语法树之间的差异 类
  • 关键字 CONSTRAINT 在此 CREATE TABLE 语句中起什么作用

    我正在学习如何将 sqlite3 与 python 一起使用 我所关注的教科书中的示例是一个数据库 其中每个国家 地区记录都有一个地区 国家 地区和人口 书上说 以下代码片段使用 CONSTRAINT 关键字来指定 表中没有两个条目是 所创
  • 使用 Javascript 的 8 位异或校验和

    我正在尝试模仿 Windows 应用程序格式化消息并发送通过 USB 通过 UART 传输到显示该消息的设备 该应用程序计算checksum并将其粘贴到消息后面 否则设备将不会接受该命令 校验和不是 crc8 校验和 但它是什么 使用 US
  • 使用 powershell 从路径获取最新创建的文件夹

    如何使用 Windows PowerShell 从路径获取最新创建的文件夹 我有路C temp我想在此路径中找到最近创建的文件夹 PowerShell 主要与管道一起工作 因此您编写的大部分内容将包括创建表示某些信息的对象 以及过滤和操作它
  • 查找最近一小时内产生的记录

    我有一个smalldatetime字段命名myTime创建记录时进行记录 我需要选择过去一小时内创建的记录的语法 我认为会是 and DATEDIFF hh datePart hh myTime DatePart hh GETDATE lt
  • 是否可以保留自定义元素的内部 html?

    使用自定义元素 我想对自定义元素内的元素进行样式设置 但是当我定义该元素时 除了影子 dom 之外的所有内容都会消失 如何将内容从元素移动到 Shadow dom 我已经有一个包装元素 div class wrapper 在阴影内 但尝试使
  • Keras:将预测与使用标准化数据训练的模型结合使用?

    我正在 Keras 中创建一个深度神经网络 以使用表格数据执行 NN 回归 最佳实践是标准化输入和输出序列 我也想使用predict函数提供各种输入集的模型输出估计 如果训练数据已标准化 我想我还需要标准化predict使用相同的缩放参数的
  • 温莎城堡延迟加载服务

    有时 我发现自己处于这样的情况 只有在满足特定条件时才需要解决服务 例如 用户可以选择发送电子邮件或短信通知 我想根据用户的选择来延迟加载电子邮件或短信服务 这样我就不必同时加载它们并浪费资源 例如 如果用户有 10 个选项怎么办 我遇到的
  • Node.js Express - 如何将 Stylus .styl 文件编译为 CSS

    我正在尝试从 Balloons http balloons io 开始构建一个应用程序 它使用 Backbone js 和 Express 来设置 UI 我从未使用过这些框架 而且我很难真正做出改变 据我了解 styl 文件被编译成 CSS
  • /etc/lsb-release 与 /etc/os-release

    我需要使用 bash 找出我正在运行的 Linux 发行版 成立这一页 https www cyberciti biz faq find linux distribution name version number 这非常有帮助 但是我的系
  • XSLT 和 xpath v1.0 查找重复项并聚合

    我想知道是否有一种方法可以在 xml 中搜索重复项 然后在找到时将所有重复项聚合到一个节点 埃克斯
  • 为什么我的 PDO 不起作用?

    我开始使用 PDO 并使用 PDO 成功连接到 MySQL 但是 当我尝试从数据库中选择内容时 什么也没有发生 没有任何回声 即使我在该表中有记录 并且列 username 存在 我的 PHP 日志中没有错误 我正在使用 MAMP 并且所有
  • 如何在 Objective-C 中编写调用 `super` 实现的 c 函数? [复制]

    这个问题在这里已经有答案了 我需要实现一个通用 C 函数 它将调用super的实现并返回值 我将在运行时将此函数注入到目标类中 目标选择器的参数数量可以是任意数量 并且只有在运行时才知道 我实现了一个C函数 如下所示 但我不知道如何调用su