2009-07-14 12 views
3

Ich brauche wirklich eine Klarstellung - ich habe ein paar Fragen und ich bin jetzt alle durcheinander.Zeiger, Primitive und Eigenschaften in Objective-C-Klassen

Hier ist eine einfache Klasse, Schnittstelle:

#import <UIKit/UIKit.h> 

@interface Car : NSObject{ 
    NSInteger carID; 
    NSString *carName; 
} 

@property (nonatomic, assign) NSInteger carID; 
@property (nonatomic, copy) NSString * carName; 
@end 
  1. Warum ist carID nicht als Zeiger deklariert?
  2. Warum verwendet "assign" für carID statt "kopieren"?
  3. Warum überhaupt Klassenmitglieder als Zeiger deklarieren? (In meinem Hauptprogramm, wird mein Auto Objekt als Zeiger verwendet werden.)

Antwort

5

NSInteger ist einfach ein typedef für einen primitiven Typen (int auf 32-Bit, long auf 64-Bit) - es ist nicht ein Objekt und kann als solches nicht beibehalten oder kopiert werden.

Klassenmitglieder sind immer Zeiger; Du gibst nie die "echten" Objekte herum; als wäre das im besten Fall unhandlich.

Bearbeiten: Um auf den letzten Absatz zu erweitern: Objective-C-Klasseninstanzen existieren immer auf dem Heap, niemals auf dem Stapel; Dies dient dazu, Dinge wie Referenzzählung und selbstverwalteten Objektlebenszyklus zu erleichtern.

Dies bedeutet auch, dass es sehr schwer ist, versehentlich ein Objekt zu kopieren; aber auf der anderen Seite kann es etwas einfacher sein, versehentlich ein Objekt zu entsorgen, das Sie noch brauchen. Letzteres ist jedoch leichter zu debuggen (da es einen schönen, großen Crash (bestenfalls, jedenfalls)) als das letzte (was im schlimmsten Fall ein langsames Leck verursacht) verursacht.

+3

Andere einfache alte Datentypen, die wie Klassen aussehen: 'NSUInteger' (unsigned lang),' CGPoint', 'CGRect',' NSRange' (Strukturen), 'CGFloat' (double) –

+0

Ah ok Weil in C++ können Sie haben Ganzzahlige Zeiger. Aber nicht in Objective C. – qstar

+0

Eigentlich können Integer-Zeiger in Objective-C haben, da Sie in C können. Zeiger auf Primitive werden jedoch im Allgemeinen verwendet, wenn eine andere Funktion/Methode einen primitiven Wert direkt an eine bestimmte Adresse schreiben soll . Wenn Sie Objective-C-Eigenschaften verwenden, müssen Sie dies nicht tun, da Sie den in der Instanzvariablen bereitgestellten Wert kopieren. –

1

Die Eigenschaft für carID ist nicht wirklich korrekt. Für Typen, die keine Zeiger sind, sieht die korrekte Definition wie:

@property (nonatomic) NSInteger carID; 

Es ist immer einen Wert Kopieren sowieso werden, aber „kopieren“ eine ganz andere Bedeutung in Eigenschaften hat - für Objekte nennt es geht [object Kopieren], wenn diese Eigenschaft zum Festlegen eines neuen Werts verwendet wird.

Oder Sie könnten die nonatomic fallen lassen, aber dann ist die Eigenschaft teurer zu nennen (durch eine kleine Menge). Lass es einfach im Nichtatomaren, außer du hast einen guten Grund, es nicht zu tun.

0

Danke Jungs!

Also in Objective-C haben Sie Int und Pointer Int.

Wie erklären Sie diese in Objective C

-int regelmäßig int sein.

-Pointer Int ist eine Objektdarstellung einer Ganzzahl. Da es sich um ein Objekt handelt, kann es auch auf Zeiger * zeigen. Recht?

Und Zeiger Int Zeiger können auf Zeiger aller Art zeigen, wenn ich wollte. Recht? Es wird einen Absturz verursachen, wenn es nicht auf einen Zeiger int zeigt. Aber es wird erfolgreich kompilieren, oder?

Aber in welchen Szenarien würde ich lieber einen regulären Int zu einem Zeiger Int verwenden?

+0

"Zeiger Int" wäre in diesem Fall wahrscheinlich ein NSNumber-Objekt. Es würde als NSNumber * myInt deklariert werden. Um den Integer-Wert tatsächlich zu erhalten, müssten Sie [myInt intValue] aufrufen. Wenn Sie nur einen Zähler haben wollen, werden Sie nur ein primitives int wollen. Der einzige Grund für eine NSNumber besteht darin, sie an Objekte zu übergeben, die Objekte wie NSArray oder NSDictionary erfordern. –

0

Ich möchte eine Klarstellung hinzuzufügen, warum Sie verwenden wollen:

@property (nonatomic, copy) NSString * carName; 

statt

@property (nonatomic, retain) NSString * carName; 

Die Kopie Stichwort impliziert Sprache Semantik, dass Sie eine Kopie der NSString haben wollen in Ihre aktuelle Objektreferenz übernommen. Der Zeiger ändert sich also nicht (deshalb müssen Sie das Objekt ref nicht freigeben).

Das retain-Schlüsselwort sorgt dafür, dass Sie den Zeiger erhalten, der beibehalten wird, da sich die Zeigerreferenz für dieses Datenelement ändert (und das aktuelle wird freigegeben). Das Kopieren eines NSS-Strings ist möglicherweise keine besonders schwere Operation, daher wird das Kopieren von NSString oft verwendet. Sie müssen vorsichtig sein, welche Art von Eigenschaft Sie als Kopie deklarieren. Es könnte ein erheblicher Aufwand sein, eine Kopie von Typen wie Dictionaries usw. zu erstellen (siehe seichte, tiefe Kopie usw.).

Hoffe, dass hilft!

+0

"Zeiger Referenz ändert sich für dieses Datenelement" - Wirklich, warum würde es ändern? - Ich würde denken, dass, sobald ein Speicherobjekt im Heap zugeordnet ist, bleibt es dort nicht? – qstar

+0

was ich meinte ist, dass es jetzt auf etwas anderes zeigt, nicht auf das, was es vorher gezeigt hat! – fnCzar

+1

nur versuchen, meinen Kopf um diese zu wickeln ok vielen Dank – qstar