eine Nachricht in Objective-C gesendet wird, in einen Aufruf der Funktion übersetzt objc_msgSend(receiver, selector, arguments)
oder eine seiner Varianten objc_msgSendSuper
, objc_msgSend_stret
, objc_msgSendSuper_stret
.
Wenn es möglich war, die Implementierung dieser Funktionen zu ändern, konnten wir jede Nachricht abfangen. Leider ist objc_msgSend
Teil der Objective-C-Laufzeit und kann nicht überschrieben werden.
Durch Googeln fand ich ein Papier auf Google Books: A Reflective Architecture for Process Control Applications by Charlotte Pii Lunau. Das Papier führt einen Hack ein, indem der Klassenzeiger eines Objekts isa
auf eine Instanz einer benutzerdefinierten MetaObject-Klasse umgeleitet wird. Nachrichten, die für das geänderte Objekt bestimmt waren, werden somit an die MetaObject-Instanz gesendet. Da die MetaObject-Klasse über keine eigenen Methoden verfügt, kann sie auf den Forward-Aufruf antworten, indem sie die Nachricht an das geänderte Objekt weiterleitet.
Das Papier enthält nicht die interessanten Teile des Quellcodes und ich habe keine Ahnung, ob ein solcher Ansatz in Cocoa Nebenwirkungen haben würde. Aber es könnte interessant sein, es zu versuchen.
Wahrscheinlich meintest du @selector (release), nicht @selector (dealloc) –
Ja, ich meine @selector (release). Das habe ich niedlich gemacht und habe es aus irgendeinem Code eingefügt, der dealloc umgewechselt hat, aber ich wollte das nicht im Beispiel zeigen, weil es einige spezielle Probleme damit gibt. Fest. –
@LouisGerbarg Können Sie bitte einen Link zu Ihrer ursprünglichen Quelle, die swizzled release? – funroll