2015-02-20 10 views
5

Ich habe mich gefragt, warum die Zuweisung von Werten zu Eigenschaften in einer anderen Klasse EXC_BAD_ACCESS verursacht. Ich kann nicht herausfinden, warum.Objective-C-Eigenschaft Getter/Setter-Absturz EXC_BAD_ACCESS

1.) Der Wert, der an den Setter gesendet wird, ist nicht Null; 2.) Wenn Sie versuchen, den Wert zuzuweisen, EXC_BAD_ACCESS passiert, ist die Variable Null;

Die Verwendung dieses Musters sowohl in Cocoa als auch in Cocoa Touch verursacht beide EXC_BAD_ACCESS, also glaube ich nicht, dass es die Plattform ist, aber ich glaube, es ist das Muster, das ich verwende.

Meine Fragen sind, ist es, wenn die Variablen zugewiesen sind, oder ist es die Art, wie ich die Eigenschaften erstellen?

Ich habe ein Dummy-Projekt erstellt, das in den folgenden Bildern zu sehen ist.

Jede Hilfe wird geschätzt.

enter image description here

enter image description here

EDIT: einige graben tun, änderte ich den Namen der Variable Setter (nicht der Eigenschaftsname) zu firstName__. Grundsätzlich wird der Code in dem Setter für setFirstName:

- (void)setFirstName:(NSString *)firstName__ 
{ 
    self.firstName = firstName__; 
} 

Dadurch eine wenig Verwirrung, indem er sagt firstName__ aufgeklärt (und nicht self.firstName) gleich Null, auch wenn in der AppDelegate, ist der Wert nicht Null.

+0

Vergessen zu erwähnen, ich kann das gewünschte Ergebnis erhalten Indem Sie die gleichen Setter in AppDelegate verwenden und sie in PersonInfo.m entfernen und @synthesize firstName, lastName hinzufügen; Anruf. – ReverseEffect

+0

AFAIK, müssen Sie nicht mehr Setter/gettings OR erstellen oder synthetisieren. Fügen Sie einfach die Eigenschaften zur Kopfzeile hinzu und Sie sollten gut gehen. Wenn Sie andere Dinge tun möchten, wenn eine Variable festgelegt ist, ist das Überschreiben des Setter erforderlich. – Mike

Antwort

11

Ihr Problem ist Rekursion. Im Setter rufen Sie die Setter-Methode erneut und immer wieder auf. Wenn Sie erklären

self.firstName = first name__; 

ist im Grunde das Äquivalent von

[self setFirstName:first name__]; 

So ist die Methode selbst ruft die tun nicht viel Sinn machen.

Sie müssen sich zuerst mit Eigenschaften und Instanzvariablen beschäftigen.

Objective C-Klasseninstanzen enthalten oft Instanzvariablen, die Werte enthalten. Auch wenn es möglich ist, diese Variablen über @public-Qualifikationsmerkmal der Außenwelt zugänglich zu machen, ist dies nicht die etablierte Konvention. Die Konvention ist, Eigenschaften zu haben, die hinter den Kulissen ein "Wrapper" um private Instanzvariable sind. Da in Objective C Sie nur über Nachrichten mit anderen Objekten kommunizieren können, um auf die Werte der Instanzvariablen zugreifen zu können, haben Sie Setter- und Getter-Methoden, die aufgerufen werden, wenn Sie eine entsprechende Nachricht an das Objekt senden.

Modernes Objektiv C erstellt Instanzvariable für Sie implizit, wenn Sie Eigenschaften deklarieren. Es wird oft gesagt, dass diese Eigenschaften von Instanzvariablen unterstützt werden.

Normalerweise gibt es keinen Grund, Setter und Getter explizit zu implementieren, da der Compiler dies hinter den Kulissen für Sie erledigt.(In gleicher Weise, es schafft auch diese Instanzvariablen für Sie)

Aber wenn Sie wollen Setter explizit implementieren, müssen Sie die Instanz-Variable in der Setter gesetzt, nicht auf die Setter rufen wieder selbst (über Punkt Notation Konvention) wie ich oben erläutert habe.

Implizit erstellte Instanzvariablen haben eine Namenskonvention mit Unterstrich als Präfix. In Ihrem Fall ist es

_firstName 

Wenn Sie eine Eigenschaft namens vorName erklären, erhalten Sie auch eine Instanzvariable
_firstName

Sie Setter wie diese und

-(void)setFirstName:(NSString *)firstName 
{ 
    _firstName = firstName; 
} 

aussehen sollte Getter

-(NSstring *)getFirstName 
{ 
    return _firstName; 
} 
+0

Ich sehe was du meinst. Vielen Dank für die Erklärung. – ReverseEffect