Ich habe mich gefragt, wie ich die Warnung unterdrücken kann:
Category implementiert eine Methode, die auch von ihrer Primärklasse implementiert wird.
Ich habe dies für eine bestimmte Codekategorie:
+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {
return [self aCustomFontOfSize:fontSize];
}
objective-c
clang
Doz
quelle
quelle
super
anders aufrufen .Antworten:
Mit einer Kategorie können Sie einer vorhandenen Klasse neue Methoden hinzufügen. Wenn Sie eine bereits in der Klasse vorhandene Methode erneut implementieren möchten, erstellen Sie normalerweise eine Unterklasse anstelle einer Kategorie.
Apple-Dokumentation: Anpassen vorhandener Klassen
Zwei Methoden mit genau derselben Signatur in derselben Klasse würden zu unvorhersehbarem Verhalten führen, da nicht jeder Aufrufer angeben kann, welche Implementierung er möchte.
Sie sollten also entweder eine Kategorie verwenden und Methodennamen angeben, die für die Klasse neu und eindeutig sind, oder eine Unterklasse, wenn Sie das Verhalten einer vorhandenen Methode in einer Klasse ändern möchten.
quelle
Obwohl alles, was gut gesagt wurde, korrekt ist, beantwortet es Ihre Frage, wie die Warnung unterdrückt werden kann, nicht wirklich.
Wenn Sie diesen Code aus irgendeinem Grund haben müssen (in meinem Fall habe ich HockeyKit in meinem Projekt und sie überschreiben eine Methode in einer UIImage-Kategorie [Bearbeiten: dies ist nicht mehr der Fall]) und müssen Sie Ihr Projekt zum Kompilieren bringen können Sie
#pragma
Anweisungen verwenden, um die Warnung wie folgt zu blockieren:Ich habe die Informationen hier gefunden: http://www.cocoabuilder.com/archive/xcode/313767-disable-warning-for-override-in-category.html
quelle
Eine bessere Alternative (siehe bneelys Antwort darauf, warum diese Warnung Sie vor einer Katastrophe bewahrt) ist die Verwendung von Methoden-Swizzling. Durch die Verwendung von Methoden-Swizzling können Sie eine vorhandene Methode aus einer Kategorie ersetzen, ohne die Unsicherheit darüber zu haben, wer "gewinnt", und gleichzeitig die Möglichkeit zu bewahren, die alte Methode aufzurufen. Das Geheimnis besteht darin, der Überschreibung einen anderen Methodennamen zu geben und sie dann mithilfe von Laufzeitfunktionen auszutauschen.
Definieren Sie dann Ihre benutzerdefinierte Implementierung:
Überschreiben Sie die Standardimplementierung mit Ihrer:
quelle
Versuchen Sie dies in Ihrem Code:
UPDATE2: Fügen Sie dieses Makro hinzu
quelle
Sie können die Methoden-Swizzling verwenden, um diese Compiler-Warnung zu unterdrücken. Hier ist, wie ich die Methode Swizzling zum Zeichnen von Rändern in einem UITextField implementiert habe, wenn wir einen benutzerdefinierten Hintergrund mit UITextBorderStyleNone verwenden:
quelle
Übergeordnete Eigenschaften gelten für eine Klassenerweiterung (anonyme Kategorie), jedoch nicht für eine reguläre Kategorie.
Laut Apple Docs, die eine Klassenerweiterung (anonyme Kategorie) verwenden, können Sie eine private Schnittstelle zu einer öffentlichen Klasse erstellen, sodass die private Schnittstelle die öffentlich zugänglichen Eigenschaften überschreiben kann. dh Sie können eine Eigenschaft von readonly in readwrite ändern.
Ein Anwendungsfall hierfür ist, wenn Sie Bibliotheken schreiben, die den Zugriff auf öffentliche Eigenschaften einschränken, während dieselbe Eigenschaft einen vollständigen Lese- / Schreibzugriff innerhalb der Bibliothek benötigt.
Apple Docs Link: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/CustomizingExistingClasses/CustomizingExistingClasses.html
Suchen Sie nach " Klassenerweiterungen verwenden, um private Informationen auszublenden ".
Diese Technik gilt also für eine Klassenerweiterung, jedoch nicht für eine Kategorie.
quelle
Kategorien sind eine gute Sache, aber sie können missbraucht werden. Wenn Sie Kategorien schreiben, sollten Sie bestehende Methoden grundsätzlich NICHT erneut implementieren. Dies kann zu seltsamen Nebenwirkungen führen, da Sie jetzt Code neu schreiben, von dem eine andere Klasse abhängt. Sie könnten eine bekannte Klasse brechen und Ihren Debugger auf den Kopf stellen. Es ist einfach schlechte Programmierung.
Wenn Sie es tun müssen, sollten Sie es wirklich unterordnen.
Dann der Vorschlag des Swizzling, das ist ein großes NEIN-NEIN-NEIN für mich.
Das Swizzing zur Laufzeit ist ein komplettes NO-NO-NO.
Sie möchten, dass eine Banane wie eine Orange aussieht, aber nur zur Laufzeit? Wenn Sie eine Orange wollen, dann schreiben Sie eine Orange.
Lass keine Banane aussehen und benimm dich wie eine Orange. Und noch schlimmer: Verwandeln Sie Ihre Banane nicht in einen Geheimagenten, der Bananen weltweit leise sabotiert, um Orangen zu unterstützen.
Huch!
quelle
Ich hatte dieses Problem, als ich eine Delegatmethode in einer Kategorie anstelle der Hauptklasse implementierte (obwohl es keine Implementierung der Hauptklasse gab). Die Lösung für mich bestand darin, die Header-Datei der Hauptklasse in die Header-Datei der Kategorie zu verschieben. Dies funktioniert einwandfrei
quelle