Verwendung von (id) in Objective-C

7

Ich habe eine Funktion, die ich an zwei verschiedenen benutzerdefinierten Objekten ausführen möchte. Mein erster Gedanke war, das Argument als (id) zu akzeptieren und mit dem id-Objekt zu arbeiten. Ich kann jedoch nicht wirklich herausfinden, wie das geht.

Beide Klassen (zB Äpfel und Orangen) haben Interface-Variablen:

%Vor%

Ich möchte etwas Ähnliches tun:

%Vor%

Ich kann die Syntax nicht herausfinden, um das zu ermöglichen. Ist dies der richtige Ansatz, oder wäre es besser, eine Unterklasse (von einer Fruchtklasse) und die Elternklasse zu betreiben?

%Vor%     
Jason George 30.07.2009, 18:06
quelle

5 Antworten

12

Sie können zwar eine Nachricht an ein beliebiges Objekt (id) senden - Eigenschaftenaccessoren erfordern jedoch, dass der Compiler den Typ kennt, mit dem Sie es zu tun haben. Dies liegt daran, dass Eigenschaftenaccessoren syntaktischer Zucker sind, um spezifische Getter- und Settermethoden aufzurufen. p>

Sie haben einige Möglichkeiten, dies zu umgehen:

  1. Rufen Sie statt der Eigenschaft count die entsprechenden [getCount] -Methoden auf.

  2. Wenn die verschiedenen Klassen verschiedene Versionen dieser Methode haben, können Sie eine Laufzeittypprüfung verwenden:

  3. Stellen Sie eine Basisklasse für beide Typen bereit, so dass Sie etwas spezifischeres als (id) übergeben können.

  4. Definieren und implementieren Sie ein Protokoll, das beide Objekte implementieren und eine count-Eigenschaft (oder Methode) definieren.

Beispiel für eine dynamische Typprüfung:

%Vor%

Persönlich bevorzuge ich eine starke Eingabe in meinen Code, da dies das Verständnis der Absicht erleichtert. Darüber hinaus kann die IDE Ihren Programmieraufwand durch Intellisense-, statische Analyse- und Refactoring-Funktionen unterstützen. In Ihrem Fall würde ich entweder # 3 oder # 4 als Ansatz verwenden - je nachdem, ob die Vererbung wirklich für das Problem geeignet ist.

    
LBushkin 30.07.2009, 18:25
quelle
8

Sie sollten versuchen, nicht auf Instanzvariablen von einer anderen Klasse zuzugreifen.

In Objective-C genügt es, dass die beiden Objekte auf denselben Selektor antworten (zB count ), aber das würde Ihnen eine Compiler-Warnung geben.

Es gibt zwei Möglichkeiten, wie Sie diese Warnung loswerden können: entweder durch Unterklassenbildung von einer gemeinsamen Fruit -Klasse oder indem Sie Ihre beiden Klassen einem Protokoll anpassen. Ich würde mit dem Protokoll gehen:

%Vor%

Dann kann Ihre Methode wie folgt aussehen:

%Vor%

Hier sagen Sie, dass Ihr addCount jedes Objekt erwartet, das dem FruitProtocol -Protokoll entspricht und daher auf den count -Selektor antworten kann, damit der Compiler es akzeptiert.

    
pgb 30.07.2009 18:35
quelle
1

Die Tatsache, dass Sie versuchen, auf "addFruit.count" zuzugreifen, ist das Problem. Die Punktsyntax gilt nur für Eigenschaften, die mit @property (oder für Strukturen) deklariert sind. Wenn Sie es zu

ändern %Vor%

und fügen Sie

hinzu %Vor%

zu jeder Klasse, dann würde es funktionieren. Sie werden jedoch feststellen, dass eine Warnung angezeigt wird, dass "id" möglicherweise nicht auf die Nachricht "count" reagiert. Wenn Sie nicht absolut sicher sein können, dass die an diese Methode gesendeten Elemente eine "count" -Methode implementieren, ist dies ein problematischer Ansatz .

Ich stimme dem Vorgehen von pgb zu. Sie sollten ein Protokoll definieren und beide Klassen für die Implementierung dieses Protokolls deklarieren. Dies beseitigt das Problem, nicht zu wissen, ob das Objekt auf "zählen" reagiert oder nicht, da Sie nun einen "Vertrag" haben.

Wenn Sie die Punktsyntax mit einer Eigenschaft beibehalten möchten, können Sie dies im Protokoll deklarieren:

%Vor%

und dann wäre deine Funktion:

%Vor%     
bobDevil 30.07.2009 21:26
quelle
0

Sie senden die Nachricht zum Zählen, was zählt? id ist ein Zeiger auf einen beliebigen Objekttyp. Wenn Sie erwarten, dass das Objekt eine count -Eigenschaft hat, dann sollten Sie nur in der Lage sein, ein Array (oder eine andere Art von Einschränkung) zu übergeben.

%Vor%     
Gordon Gustafson 30.07.2009 18:14
quelle
0

Wie ich es verstehe, sind id keine Methoden oder Variablen zugeordnet, da es sich um einen generischen Zeiger handelt, der sich nicht auf eine bestimmte Klasse bezieht. Diese Seite enthält einige gute Informationen zu IDs, wenn Sie ein wenig nach unten blättern.

einObjekt, das keine count Variable hat, weshalb dein erster Versuch nicht funktioniert. Eine Basisklasse zu erstellen und diese als Parameter für die Methode zu verwenden scheint mir die beste Idee zu sein.

    
jergason 30.07.2009 18:23
quelle

Tags und Links