Ich habe in ShareKit auf diesen Code gestoßen, und ich verstehe nicht, was der Autor im Sinn hatte, indem er self
in einer Klassenmethode verwendet. Es gibt eine Warnung: Inkompatible Zeigertypen, die 'Class' an den Parametertyp id<FBSessionDelegate>
senden. Ich möchte diese Warnungen aufräumen, damit ich diejenigen sehen kann, die später wehtun könnten. Was kann / sollte ich tun, dass das nicht bricht?
Dies ist die Datei SHKFacebook.m und der Klassenname ist SHKFacebook
%Vor% self
kann in einer Klassenmethode als polymorphe Klasseninstanz verwendet werden.
Daher kann die Klassenmethode new
wie folgt implementiert werden:
und würde den korrekten Typ für die Klasseninstanz zurückgeben, die mit einer Nachricht versehen ist:
Beispiel:
%Vor%ex b:
%Vor%Siehe Hinweis unten.
Sie müssen also wirklich darauf achten, dass es nur Instanzmethoden im Protokoll gibt und dass die Methoden des (Selbst-) Selbst die Methoden der Instanz im Protokoll übernehmen.
Soweit das Design ... nun, sagen wir einfach, ich hätte es nicht so geschrieben. Ein Singleton wäre klarer und korrekter gewesen, aber ich mag Singles nicht einmal, also hätte ich diesen Weg nicht genommen.
Die Warnung wird ausgegeben, weil die Klasse -Instanz (was übergeben wird) die vom Parameter @protocol
angegebene delegate
übernimmt. Die Class
-Instanz ist keine Instanz der Klasse. Eine Protokolldeklaration gilt wirklich für Instanzen der Klasse. Wenn Sie beispielsweise NSLocking
übernehmen, erwartet der Compiler, dass Sie auch Klassenmethoden für jede Instanzmethode implementieren, die im Protokoll deklariert ist? Antwort: Niemals. Die Implementierung, mit der Sie es zu tun haben, ist IMO einer der Fälle, in denen es einen Missbrauch der Sprache gibt, aber es funktioniert.
Um die Terminologie zu verdeutlichen:
Die Class
-Instanz ist self
in einer Klassenmethode:
Eine "Instanz der Klasse" ist self
in einer Instanzmethode:
In der Praxis gibt -[NSObject conformsToProtocol:]
ist +[NSObject conformsToProtocol:]
und +[NSObject class]
gibt nur self
zurück, so dass keine Fehler bei der Ausführung auftreten.
Ich bin immer noch nicht klar, warum ich eine Warnung erhalte, wenn der Code die von dir beschriebenen Kriterien erfüllt.
Die von mir beschriebenen Kriterien gelten für die Ausführung , weichen aber von der Semantik der Sprache ab - der Compiler ist damit absolut korrekt.
Zur Lösung des Problems: Es gibt keine Möglichkeit, den Compiler "Meine Klasseninstanz entspricht dem Protokoll " mitzuteilen, da die Annahmeerklärung für Instanzen der Klasse gilt.
Sie haben zwei Hauptoptionen:
Der saubere, korrekte Ansatz: Verwenden Sie eine Instanz der Klasse und implementieren Sie das Protokoll wie definiert.
oder Geben Sie die Klasseninstanz an das Protokoll an:
ID Delegat = (ID) selbst; fbSession = [FBSession sessionForApplication: SHKFacebookKey getSessionProxy: SHKFacebookSessionProxyURL Delegierter: Delegierter];
Wenn Sie # 2 wählen, kann es hilfreich sein, die Instanzmethoden des Protokolls so zu definieren, dass Klassenmethoden verwendet werden:
%Vor%Das würde auch bedeuten, dass Sie nie Instanzen benötigen. Es würde helfen, weil es Warnungen hinzufügt, wenn das Protokoll sich ändert. Diese Warnungen würden zu Klassenmethoden führen, wenn Sie der Konvention folgen.
Um Rauschen zu reduzieren, können Sie auch eine Methode zum Reduzieren der Typumwandlung an einem Ort erstellen:
%Vor%Dann kannst du einfach schreiben:
%Vor%(Beachten Sie, dass die Implementierungen dieser Typen tatsächlich Klassencluster sind und Sie im Debugger oder beim Drucken etwas anderes sehen werden)
Tags und Links objective-c class-design class-method objc-protocol