如何使用 Swift 中的协议公开 Objective-C 对象的私有类方法?

2024-02-25

考虑两个私有方法UIColor:

  1. 实例方法styleString返回颜色的 RGB 字符串
  2. 类方法_systemDestructiveTintColor它返回破坏性按钮使用的红色。

UIColor.h 私有标头供参考 https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIColor.h

例如方法,我可以创建一个@objc协议和使用unsafeBitCast公开私有方法:

@objc protocol  UIColorPrivate {
    func styleString() -> UIColor
}

let white = UIColor.whiteColor()
let whitePrivate = unsafeBitCast(white, UIColorPrivate.self)
whitePrivate.styleString() // rgb(255,255,255)

但是,我不确定这对于类方法如何工作。

第一次尝试:

@objc protocol UIColorPrivate {
    class func _systemDestructiveTintColor() -> String // Error: Class methods are only allowed within classes
}

有道理,我改一下static:

@objc protocol UIColorPrivate {
    static func _systemDestructiveTintColor() -> String
}

let colorClass = UIColor.self
let privateClass = unsafeBitCast(colorClass, UIColorPrivate.self) // EXC_BAD_ACCESS

这会导致崩溃。好吧,这不会很快发生。我可以使用桥接标头并将类方法公开为@interface,但是有没有办法在纯 Swift 中公开这些私有类方法呢?

我可以这样做performSelector,但我宁愿将该方法公开为接口或协议:

if UIColor.respondsToSelector("_systemDestructiveTintColor") {
    if let red = UIColor.performSelector("_systemDestructiveTintColor").takeUnretainedValue() as? UIColor {
        // use the color
    }
}

通过协议实现您想要的效果的一种方法是对静态方法使用单独的协议。中的静态方法Objective-C实际上是类的元类上的实例方法,因此您可以安全地采用如下方法:

@objc protocol UIColorPrivateStatic {
    func _systemDestructiveTintColor() -> UIColor
}

let privateClass = UIColor.self as! UIColorPrivateStatic
privateClass._systemDestructiveTintColor() // UIDeviceRGBColorSpace 1 0.231373 0.188235 1

这将使您同时暴露私有方法和协议的使用,并且您摆脱了丑陋的unsafeBitCast(并不是说强制演员会更漂亮)。

请注意,与往常一样,如果您使用私有 API,如果 Apple 决定更改类的某些内部结构,您的代码可能随时中断。

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

如何使用 Swift 中的协议公开 Objective-C 对象的私有类方法? 的相关文章

  • iPhone UINavigationBar 使用 [UINavigationBar 外观] 更改所有控制器的字体样式

    我知道我可以单独更改导航栏的字体 如本答案所述 更改导航栏的字体 https stackoverflow com questions 5832036 change the navigation bars font 目前我正在使用一种更全局的
  • 如何将字符串日期转换为 NSDate?

    我想转换字符串 2014 07 15 06 55 14 198000 00 00 to an NSDate在斯威夫特 尝试这个 let dateFormatter NSDateFormatter dateFormatter dateForm
  • 错误域=AVFoundationErrorDomain代码=-11814“无法记录”

    它不断给我错误 错误域 AVFoundationErrorDomain代码 11814 无法记录 我不确定问题是什么 我试图在拍照后计数器达到 1 时录制声音 static int counter counter will always b
  • 确定 Objective-C 方法在运行时是否是可变的

    有没有办法在运行时找出给定方法是否是可变参数类型 就像是method getTypeEncoding 这不会告诉我一个方法是否接受可变数量的参数 或者有什么技巧可以告诉我们吗 罗伯特的评论是正确的 考虑 interface Boogity
  • 使用 Interface Builder 创建 UIScrollView 的步骤

    我正在尝试使用 UIScrollView 但似乎有一些基本的事情我不理解 假设我想在我的 iPhone 应用程序中使用 UIScrollView 我有一个充满按钮的视图 尺寸为 320x700 显然 这对于 320x480 的 iPhone
  • 在真实设备上展示测试广告

    这是我的代码 let request GADRequest request testDevices kGADSimulatorID XXXX2F32d69CCA859FFB559D0FEA3CF6483D08A6 adView load r
  • Xcode 中的 iOS 9 警告 - 此文件设置为针对早于项目部署的版本进行构建。功能可能有限

    我刚刚将我的 Mac 更新到最新的操作系统 并将 Xcode 更新到最新版本 现在我收到此警告 但我不知道该由谁来删除它 也不知道它的真正含义是什么 有人可以向我解释一下吗 Thanks Select Main storyboard in
  • 检测 AvPlayer 何时切换比特率

    在我的应用程序中 我使用 AVPlayer 通过 HLS 协议读取一些流 m3u8 文件 我需要知道在流会话期间 客户端切换比特率多少次 我们假设客户端的带宽正在增加 因此客户端将切换到更高比特率的段 AVPlayer能检测到这个开关吗 T
  • iOS 循环对象的属性并添加操作

    我有一个具有几个类似属性的类 UISliders 我想添加用户开始和结束使用每个滑块时的操作 每个滑块都将链接到同一个选择器 因此我考虑只是迭代它们 而不是编写 10 个几乎相同的代码块 问题是 最有效的方法是什么 我尝试过这样的事情 在运
  • Google 地图 API -> OpenGLES 崩溃

    日志是从 Crashlytics 粘贴的 对于许多用户来说 崩溃经常发生 据我所知 它与设备 iOS 版本无关 我在我的代码中找不到任何错误 这似乎是纯粹的库问题 是 Google 地图 API 错误吗 我可以做些什么来修复它 或者我应该在
  • git 提交错误:检测到大文件

    您好 我正在为 ios 8 1 开发一个应用程序 xcode 我已经使用 googleMaps 框架来实现自动完成功能 当我尝试在 Git 中推送我的项目时 我收到大文件检测错误 后来尝试使用 git lfs 并跟踪 git 检测到的文件
  • 拖动时获取MKAnnotation的坐标

    我正在根据用户添加的注释的位置创建一条路径 MKPolyline 我想允许用户通过拖动引脚来更改路径 我目前可以做到这一点 但 MKPolyline 不会更新 直到引脚被放下 我实施了 void mapView MKMapView mapV
  • iPhone 和加密库

    我想我必须在我的 iPhone 应用程序中使用加密库 我想问你有关苹果公司实施的加密货币出口政策的影响 我需要做一些额外的事情吗 例如填写表格等 1 如果我使用 MD5 进行哈希处理 2 如果我使用对称加密 Thanks EDIT 2009
  • 如何反转 CGPath 的点顺序

    我想画一个圆圈 并用它打出字母 为此 我需要顺时针抚摸圆圈 逆时针抚摸字母 这一切都很好 但是当我使用 Core Text 获取字母路径时 我不知道如何从本质上反转该路径 不是镜像或旋转或任何东西 这很简单 我希望点笔画顺序是逆时针的 这实
  • Swift C 回调 - Swift 类指针的 takeUnretainedValue 或 takeRetainedValue

    我有一些UIView or UITableViewCell 里面我有 C 回调 例如 CCallback bridge self observer data gt Void in let mySelf Unmanaged
  • 在故事板中的视图控制器之间滑动手势

    我希望添加左右滑动手势来在视图控制器之间进行更改 这是否可能 并且有没有一种简单的方法可以在故事板中执行此操作 谢谢 故事板允许您在两个视图控制器之间设置 Segues 我想说首先在视图之间附加 Segues 给它一个标识符 然后使用类似的
  • 分发内部业务 IOS 应用程序

    我遇到了 IOS 应用程序分发的一个令人困惑的部分 因此 我需要简单细分一下我的限制 即仅将我的应用程序分发给我的员工 同事或任何被视为 内部 的人 这是表明我不希望该应用程序出现在应用程序商店中的另一种方式 我的情况是我为几家公司开发 他
  • RemoteIO 音频单元播放回调中的 AudioBufferList 内容

    我想 拦截 音频数据传送到 iOS 设备扬声器的过程 我相信这可以使用 RemoteIO 音频单元和回调来完成 在下面的playbackCallback中 ioData实际上包含任何音频数据吗 static OSStatus playbac
  • 苹果推送通知在生产中不起作用

    我们完全陷入困境 请帮忙 我和我的团队制作了一个 iPhone 应用程序 这是我们第一次在 iOS 上尝试 一切都很好 直到我们提交应用程序并在应用程序商店上可用为止 推送通知服务无法正常工作 我在网上搜索并尝试根据人们的建议仔细检查我们的
  • IPV6 快速可达性

    我是 swift 和 xcode 的新手 并且我的应用程序因 IPV6 而被拒绝 性能 2 1 当我们执行以下操作时 您的应用程序会在运行 iOS 9 3 5 并连接到 IPv6 网络的 iPad 和 iPhone 上崩溃 具体来说 当我们

随机推荐

  • Java:摆脱 `Cipher.init()` 开销

    我需要提高以下方法的性能 private byte decrypt final byte encrypted final Key key throws this cipher init Cipher DECRYPT MODE key ret
  • NetworkX 打乱节点顺序

    我是编程初学者 也是新来的 所以你好 我在 networkX 中遇到节点顺序问题 这段代码 letters G nx Graph for i in range nodesNum letter ascii lowercase i letter
  • 将 Hg 与 Grails 结合使用的最佳实践?

    我应该办理什么手续 不办理什么手续 由于许多文件有时是自动生成的 我不完全确定如何使用版本控制来处理这个问题 它与标签有关吗 例如在 ANT 中 我know不要签入我的 target bin 目录 但是 Grails 对此又增加了一层混乱
  • 如何使用 jQuery 设置跨度值

    如何设置a的值 span 使用 jQuery 标记 例如 下面是我的 span tag span span 在我的 jQuery 代码中 jQuery noConflict jQuery document ready function va
  • 使用 MEF 2 组合导出值

    使用 MEF 1 可以使用 ComposeExportedValue Method 将现有对象组合到容器中 container ComposeExportedValue 如何使用 Microsoft Composition MEF 2 来完
  • 如何在不使用触摸屏的情况下模拟触摸事件

    我目前正在尝试开发一个触摸屏应用程序 Windows 7的 视觉工作室2013 C WPF 我工作的地方将配备触摸屏 实际上是放置在平面屏幕上的一层 我希望能够生成触摸输入 以便在没有屏幕的情况下开发和测试应用程序 我找到的所有资源要么非常
  • 定制 Android 操作系统构建

    我想知道创建自定义 Android 版本并将其部署到市场上当前可用的设备上的可行性如何 是否有描述该过程的文件或指南 先感谢您 萨米 Try dsixda 的 Android 厨房 http forum xda developers com
  • JSON序列化时如何使用JavaScriptSerializer设置格式?

    我正在使用 JavaScriptSerializer 将文件中的对象序列化为 JSON 格式 但结果文件没有可读的格式 如何允许格式化以获得可读文件 你可以使用JSON NET http json codeplex com 序列化器 支持
  • Matplotlib寄生对数轴勾选不需要的镜像

    我正在尝试使用 mpl toolkits axes grid1 中的 host subplot 制作一个具有两个 y 轴的图 其中一个是对数轴 一个是线性轴 该图看起来不错 但辅助 y 轴 右 的小刻度也显示在图内部的主 y 轴 左 上 i
  • android sqlite数据库中rawquery和execSQL的区别

    使用 rawquery 和 execSQL 之间的确切区别是什么 在 android Activity 中编写查询时 何时使用 rawquery 以及何时使用 execSQL 来自 API 文档 void execSQL String sq
  • 片段 - 您是否必须在包含整个活动的片段周围使用活动包装器?

    考虑以下示例应用程序开发者 android com http developer android com images fundamentals fragments png 这描述了如何使用 Fragment 如下所示 在电话上 您可以在活
  • 是否可以将条件属性创建为 DisplayIf?

    我想创建一个与我的视图模型一起使用的属性 我想根据第三个值显示不同的文本字符串 我想做这样的事情 DisplayIf IsPropertyValid true Name value 1 DisplayIf IsPropertyValid f
  • 当第三方 C 函数返回指针时,您应该自行释放它吗?

    有许多函数 特别是在 POSIX 库中 返回指向几乎必然新分配的数据的指针 他们的联机帮助页没有说明您是否应该释放它们 或者是否有一些模糊的机制在起作用 例如返回指向静态缓冲区的指针 或者类似的东西 例如 inet ntoa http ww
  • 使用 Graphics.CopyFromScreen 以 150% 缩放比例截取屏幕截图

    我正在尝试创建屏幕截图 位图 我写了这个函数 public static Bitmap CreateScreenshot Rectangle bounds var bmpScreenshot new Bitmap bounds Width
  • Spark应用程序启动后如何更改名称?

    我在更新 重新配置名为 spark 的预定义 Spark 上下文时遇到问题 spark sparkContext conf get spark app name 返回应用程序名称 Databricks Shell 我想更新它并尝试使用 sp
  • 如何将一周 (200851) 转换为日期 (2008-12-27)?

    如何将年周 例如 0852 或 200852 转换为日期 例如 2008 12 31 或具体的一周结束日 即星期六 2008 12 27 或一周开始日 即 2008 年 12 月 21 日 周末的任何一天都可以 周五 周六 周日或周一 SQ
  • 如何调整/dev/shm的大小?

    On Ubuntu 18 04 当我跑步时 df h 我看到这个结果 Filesystem Size Used Avail Use Mounted on tmpfs 3 9G 73M 3 8G 2 dev shm dev shm大小为3 9
  • 评估一串简单的数学表达式[关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 Locked 这个问题及其答案是locked help locked posts因为这个问题是题外话 但却具有历史意义 目前不接受新的答案或互动 挑战
  • 创建一个随机数并检查它是奇数还是偶数

    我希望创建一个批处理文件 该文件在运行时创建一个从 0 到 100 的随机整数 然后通过 if 语句运行它来检查它是奇数还是偶数 我遇到了一些麻烦 所以这就是我到目前为止遇到的问题 echo off set a num random 100
  • 如何使用 Swift 中的协议公开 Objective-C 对象的私有类方法?

    考虑两个私有方法UIColor 实例方法styleString返回颜色的 RGB 字符串 类方法 systemDestructiveTintColor它返回破坏性按钮使用的红色 UIColor h 私有标头供参考 https github