【问题标题】:How to decipher "objc_method_description" from protocol method description list?如何从协议方法描述列表中破译“objc_method_description”?
【发布时间】:2017-01-06 09:03:31
【问题描述】:

我有一些 Swift 3 代码来解码 iOS Objective-C 协议(它有一个 Swift 对应协议)。在得出结论 Swift 3 反射的开发不足以完成我所需要的之后,我偶然发现了 objc 运行时方法 protocol_copyMethodDescriptionList(),它返回以下 C 结构的数组:

struct objc_method_description
     SEL name;
     char *types;
};

代码获取协议选择器名称列表,但不确定type 字段中返回的内容。我对如何正确解码 objc_method_description.type 值感到困惑。

我在 type 字段中得到的内容是一种神秘的格式,例如,"B48@0:8@16{_NSRange=QQ}24@40" 起初我认为这是我如何转换 C 字符串的问题,但经过一些研究,我怀疑它实际上 参数的编码,类似于 Java 的 JVM 传递方法签名的方式。但我仍然没有参考来解码它。

import UIKit

class ViewController: UIViewController, UITextViewDelegate {

    @IBOutlet weak var noteView : UITextView!

    func decodeProto() {
        var methodCount : UInt32 = 1
        if let methodList = protocol_copyMethodDescriptionList(UITextViewDelegate.self,
                  false, true,  UnsafeMutablePointer<UInt32>(&methodCount)) {
            for i in 0..<Int(methodCount) {
                let methodDesc = methodList[i];
                let name = methodDesc.name
                let types = String(validatingUTF8: methodDesc.types)
                print("\(name) \(types)")
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        decodeProto()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

XCode 控制台的输出是:

可选(textViewDidBeginEditing:)可选("v24@0:8@16")
可选(textViewDidEndEditing:)可选("v24@0:8@16 ")
可选(textViewShouldBeginEditing:)可选("B24@0:8@16")
可选(textViewShouldEndEditing:)可选("B24 @0:8@16")
可选(textView:shouldChangeTextInRange:replacementText:)可选("B48@0:8@16{_NSRange=QQ}24@40")
可选(textView:shouldChangeTextInRange:replacementText:) 可选("B48@0:8@16{_NSRange=QQ}24@40")
.
.
.

【问题讨论】:

  • 您打算如何处理这些信息?
  • 对,我不确定这在 Swift 中是否可行,因为你会想使用调用...
  • @jtbandes - 为了回答您的第一个问题,我正在尝试“自动化”此答案中的代码:stackoverflow.com/a/41528359/2079103。至于您的第二点-我删除了其他 cmets,因此如果现在有意义,您可以将其删除;-)

标签: objective-c swift objective-c-runtime


【解决方案1】:

objc_method_description.type 字段返回什么?

  • 一种方法签名编码方案
  • ...其中包括过时的堆栈偏移表示

换句话说,要从type 字段中获取可用 方法签名编码,只需按从左到右的顺序提取字母符号字符,丢弃数字即可。

支持文档:


【讨论】:

  • 作为一般规则,Objective-C API 中此类内容的文档是在方法级别完成的 - 在本例中,class_addMethod:developer.apple.com/reference/objectivec/… ,考虑问这个问题——这是从什么方法来的?
  • 谢谢。更新了答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 2020-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多