Sie können NSClassFromString
verwenden, um Class
abzurufen, und die Laufzeitbibliothek verwenden, um Methodenwechsel durchzuführen. Keine Header-Dateien erforderlich. Sie müssen nur den Klassennamen und die Methodensignatur kennen.
sel_getUid
kann verwendet werden, wenn @selector(somePrivateMethod)
Ihre Fehler zu somePrivateMethod
geben ist nicht gültig Selektor (weil Header nicht verfügbar ist)
-Code genommen von my Xcode plugin
SEL sel = sel_getUid("codeDiagnosticsAtLocation:withCurrentFileContentDictionary:forIndex:");
Class IDEIndexClangQueryProviderClass = NSClassFromString(@"IDEIndexClangQueryProvider");
Method method = class_getInstanceMethod(IDEIndexClangQueryProviderClass, sel);
IMP originalImp = method_getImplementation(method);
IMP imp = imp_implementationWithBlock(^id(id me, id loc, id dict, IDEIndex *idx) {
id ret = ((id (*)(id,SEL,id,id,id))originalImp)(me, sel, loc, dict, idx);
// do work
return ret;
});
method_setImplementation(method, imp);
Wenn Sie jemals versucht sind, etwas zu tun mit Private APIs, bei denen Sie das Gefühl haben, dass Sie Header-Dateien benötigen, können Sie sie einfach zurückentwickeln. Schauen Sie sich Tools wie 'class-dump' oder' class-dump-z' an. Viele Leute haben auch die Reverse-Engineering-Header online selbst gepostet. Fügen Sie diesen Header dann als Quelldatei in Ihr Projekt ein. Wenn Sie Probleme bekommen, wenn reverse-engineered Header nicht kompiliert werden, müssen Sie sie oft nur manuell überprüfen und "# imports", die Sie nicht benötigen, entfernen oder einfach die Header-Datei abschneiden, um nur die Funktion einzubeziehen, die Sie ' Interesse an. – Nate
Das war, was ich anfangs tat und dachte, dass es einen einfacheren Weg geben muss. Jedenfalls bin ich dank Bryan (siehe unten) in der Lage, diese private API zu swizzlen. Das Problem ist, dass andere Frameworks nicht swizzled werden können. Wenn ich diese Methode direkt aus meinem Testcode herausrufe, bekomme ich die Swizzled-Funktion, aber wenn diese Methode in einem anderen Framework aufgerufen wird, ruft sie meine Swizzled-Funktion nicht auf. –
Möglicherweise müssen Sie eine neue, weiterführende Frage stellen. Bitte sei auch spezifisch. Welche API möchten Sie swizzlen? Das ist nützlich, wenn Sie wissen, dass das Swizzling nicht funktioniert, wenn diese API innerhalb des Prozesses Ihrer App aufgerufen wird, aber direkt von einem Framework (nicht von Ihrem Code) aufgerufen wird? – Nate