2012-04-06 5 views
15

Das NSObject-Protokoll wird mit den Standardprotokollvorlagen geliefert, scheint aber für tatsächliche Implementierungen des Protokolls nicht unbedingt erforderlich zu sein. Es wegzulassen, scheint absolut nichts zu ändern. Also, ist es wirklich notwendig, dass ein Protokoll davon erbt, oder ist es nur ein unnötiges Add-On?müssen Protokolle dem NSObject Protokoll entsprechen?

Antwort

19

Seit Jahren ich (und viele wie Ich habe unsere Protokolle nicht konform zu <NSObject> gemacht. Es funktioniert gut. Aber es kann oft nervig sein. Die häufigste Belästigung ist, dass Sie respondsToSelector: nicht verwenden können, ohne auf NSObject* zurück zu werfen (was den ganzen Punkt eines Protokolls besiegt). Das war in den ObjC1-Tagen nicht von Bedeutung, da es keine @optional gab, also machte sich keiner von uns Sorgen darüber (wir haben in jenen Tagen überhaupt keine Protokolle verwendet, da sie ohne @optional nicht so nützlich waren). Dann kam ObjC2 mit dem wunderbaren Zusatz von optionalen Methoden und plötzlich respondsToSelector: zählte. Es dauerte eine Weile für die langsameren von uns, aber schließlich begannen wir herauszufinden, dass das Leben viel einfacher war, wenn Sie Ihre Protokolle konform zu <NSObject> machen. Glücklicherweise ist dies jetzt in Xcode angekommen, was es für jeden einfacher macht, die Dinge bequemer zu erledigen.

Aber nein, Sie müssen es nicht tun. Es ist in vielen Fällen nicht wichtig. Aber es gibt keinen Grund, es nicht zu tun, also empfehle ich es.

+0

Große Antwort ... Aber selbst der Ärger, den Sie mit NSObject Protokoll erwähnen, würde nur mit 'id obj' ins Spiel kommen, denn wenn Sie das Objekt mit einer Klasse referenzieren, wird der Compiler die Vererbung ... Which Beginnt vermutlich mit NSObject ... –

6

Nicht unbedingt. Ein Delegat ist nur ein Hilfsobjekt - die einzigen Anforderungen sind diejenigen, die die delegierende Klasse darauf legt. Wenn Sie die Anforderungen für einen bestimmten Delegaten formalisieren möchten, erstellen Sie ein formales Protokoll, d. H. Deklarieren Sie ein Protokoll mit der Direktive @protocol. Wenn konforme eine der Anforderungen an das NSObject Protokoll ist, können Sie Ihr Protokoll machen annehmen:

@protocol MyDelegateProtocol <NSObject> 
//... 
@end 

Das heißt, ich sehe keinen Grund, einen Delegierten zu schaffen, die nicht von NSObject abgeleitet ist oder vielleicht NSProxy, und diese beiden Klassen entsprechen bereits dem NSObject-Protokoll.

+0

Kann ein von NSObject abgeleiteter Delegat unterbrochen werden, wenn das Protokoll NSObject nicht entspricht? (Mit anderen Worten, stimmt nicht überein, dass Delegierte Methoden nicht aufgerufen werden)? – CodaFi

+2

Da NSObject dem NSObject-Protokoll entspricht, entspricht jede von NSObject abgeleitete Klasse auch dem NSObject-Protokoll. Nein, ein von NSObject abgeleiteter Delegat bricht nicht ab, nur weil das Delegate-Protokoll, das er annimmt, das NSObject-Protokoll nicht explizit annimmt. – Caleb

1

Nicht jedes Objekt muss eine Unterklasse NSObject sein. Ich nehme an, wenn Sie erwarten, dass ein solches Objekt Ihrem Protokoll entspricht, muss es nicht unbedingt NSObject entsprechen.

In Übereinstimmung mit NSObject wissen wir, dass das Objekt den Grundlagen entspricht - überprüfen Sie es NSObject Protocol Reference. Ohne zu sagen, dass ich mit NSObject übereinstimme, wie weiß der Compiler, dass ich mich an etwas davon anpasse?

NSObject ist definiert als

@interface NSObject <NSObject> { 
    Class isa; 
} 

während id als

typedef struct objc_object { 
    Class isa; 
} *id; 

für id So definiert der Compiler nicht weiß, es NSObject entspricht

1

Empfehlen und nicht verpflichtend.

Laut Apple offiziellen Dokument ProgrammingWithObjectiveC.pdf

Wenn Sie die respondsToSelector: Methode einer ID zu nennen versuchen dem Protokoll entsprechen, wie es oben definiert ist, erhalten Sie einen Compiler Fehlermeldung erhalten dass es keine bekannte Instanzmethode dafür gibt.Sobald Sie eine ID mit einem Protokoll qualifizieren, kommt allstatic Typ-Überprüfung zurück; Sie erhalten einen Fehler, wenn Sie versuchen, eine Methode aufzurufen, die nicht im angegebenen Protokoll definiert ist. Eine Möglichkeit, den Compilerfehler zu vermeiden, besteht darin, das benutzerdefinierte Protokoll so einzurichten, dass das NSObject-Protokoll übernommen wird.

das Protokoll, wie es oben definiert ist ist ein Protokoll ohne NSObject Protokoll entspricht.

Als Beispiel ist es am besten Praxis Ihre Protokolle definieren zum NSObject Protokoll wird von seiner Klasse Schnittstelle in ein separates Protokoll aufgeteilt (einige der NSObject Verhalten anzupassen; der Klasse NSObject die Annahme NSObject-Protokoll).

Verwandte Themen