Self-in-Class-Methode verwenden

8

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%     
Jim 27.01.2012, 03:14
quelle

1 Antwort

13

self kann in einer Klassenmethode als polymorphe Klasseninstanz verwendet werden.

Daher kann die Klassenmethode new wie folgt implementiert werden:

%Vor%

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:

%Vor%

Eine "Instanz der Klasse" ist self in einer Instanzmethode:

%Vor%

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:

  1. Der saubere, korrekte Ansatz: Verwenden Sie eine Instanz der Klasse und implementieren Sie das Protokoll wie definiert.

  2. 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)

    
justin 27.01.2012, 03:39
quelle