2017-01-06 1 views
1

Ich habe Swift 3 Code um ein iOS Objective-C Protokoll zu dekodieren (welches ein Swift Gegenstück hat). Swift 3 Reflexion Nach Abschluss wurde nicht entwickelt genug, um zu erreichen, was ich brauchte, stolperte ich auf dem objc Laufzeitverfahren protocol_copyMethodDescriptionList(), die eine Reihe der folgenden C structs zurück:Wie "objc_method_description" aus der Liste der Protokollmethoden entschlüsseln?

struct objc_method_description 
    SEL name; 
    char *types; 
}; 

Der Code ruft eine Liste der Protokoll-Auswahl Namen , aber nicht sicher, was im Feld type zurückgegeben wird. Ich bin verwirrt, wie man objc_method_description.type Werte richtig decodiert.

Was ich in dem die type Feldern immer in einem kryptischen Format, zum Beispiel "[email protected]:[email protected]{_NSRange=QQ}[email protected]" Zuerst dachte ich, es ist ein Problem in war, wie ich C-Strings wurde Umwandlung, aber nach einiger Studie, ich vermute, dass es tatsächlich ist eine Codierung der Parameter, ähnlich, wie Java JVM Methodensignaturen umgeht. Aber ich habe immer noch keinen Hinweis, um es zu entschlüsseln.

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() 
    } 
} 

Der Ausgang des in der XCode Konsole ist:

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

+0

Was Sie mit diesen Informationen planen zu tun? – jtbandes

+0

Richtig, ich bin nicht sicher, ob dies in Swift möglich ist, weil Sie Aufrufe verwenden möchten ... – jtbandes

+0

@jtbandes - Um Ihre erste Frage zu beantworten, versuche ich den Code in dieser Antwort zu "automatisieren": http : //stackoverflow.com/a/41528359/2079103. Was deinen zweiten Punkt anbelangt - ich habe die anderen Kommentare gelöscht, so dass du das entfernen kannst, wenn es jetzt Sinn macht ;-) – clearlight

Antwort

2

Was wird zurückgegeben objc_method_description.type Feld?

  • Verfahren Signatur Codierschema
  • ... die

Mit anderen Worten: eine obsolet Stapel Offset Darstellung enthält, eine brauchbare Methodensignatur-Codierung aus dem type Feld zu bekommen, extrahieren Sie einfach die Alpha-symbolischen Zeichen in der Reihenfolge von links nach rechts und verwerfen die Ziffern.

Supporting Dokumentation:


+1

In der Regel wird die Dokumentation für diese Art von Dingen in den Objective-C APIs auf Methodenebene durchgeführt - in diesem Fall class_addMethod: https://developer.apple.com/reference/objectivec/1418901-class_addmethod?language=objc Wenn Sie das nächste Mal auf eine Ganove-Chase stoßen, überlegen Sie, ob Sie die Frage stellen - welche Methode ist das? von? –

+0

Danke. Aktualisierte Antwort – clearlight