2015-02-20 13 views
5

Mi chiedevo perché l'assegnazione dei valori alle proprietà in un'altra classe causasse EXC_BAD_ACCESS. Non riesco a capire perché.Errore Getter/Setter proprietà Objective-C EXC_BAD_ACCESS

1.) Il valore inviato al setter è diverso da zero; 2.) Quando si tenta di assegnare il valore, si verifica EXC_BAD_ACCESS, la variabile è nulla;

L'utilizzo di questo modello in entrambe le applicazioni Cocoa e Cocoa Touch causa entrambe EXC_BAD_ACCESS, quindi non penso che sia la piattaforma, ma credo che sia lo schema che sto utilizzando.

Le mie domande sono, è quando le variabili sono assegnate, o è il modo in cui sto creando le proprietà?

Ho creato un progetto fittizio che viene visualizzato nelle immagini seguenti.

Qualsiasi aiuto è apprezzato.

enter image description here

enter image description here

EDIT: Facendo qualche ricerca, ho cambiato il nome della variabile del setter (non il nome della proprietà) per firstName__. In sostanza, il codice del setter per setFirstName:

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

In questo modo chiarito un po 'di confusione dicendo firstName__ (e non self.firstName) è uguale a zero, anche se nel AppDelegate, il valore è non nil.

+0

Ho dimenticato di dire, POSSO ottenere il resu desiderato Usando gli stessi setter in AppDelegate e rimuovendoli in PersonInfo.m e aggiungendo @synthesize firstName, lastName; chiamata. – ReverseEffect

+0

AFAIK, non è più necessario creare setter/gettings o sintetizzarli. Basta aggiungere le proprietà all'intestazione e si dovrebbe essere a posto. Se vuoi fare altre cose quando è impostata una variabile, sarà necessario eseguire l'override del setter. – Mike

risposta

11

Il tuo problema è ricorsione. Nel setter, stai chiamando di nuovo il metodo setter, e ancora e ancora. Quando si dichiara

self.firstName = first name__; 

è fondamentalmente l'equivalente di

[self setFirstName:first name__]; 

Quindi il metodo sta chiamando per sé, che non ha molto senso fare.

Per prima cosa è necessario considerare le proprietà e le variabili di istanza.

Le istanze di classe C oggettive contengono spesso variabili di istanza che contengono valori. Anche se è possibile esporre queste variabili all'esterno del mondo tramite il qualificatore @public, questa non è la convenzione stabilita. La convenzione deve avere proprietà, che dietro le quinte sono un "wrapper" attorno alla variabile di istanza privata . Poiché in Objective C è possibile comunicare solo con altri oggetti tramite messaggi, per poter accedere ai valori della variabile di istanza con i metodi setter e getter invocati quando si invia un messaggio appropriato all'oggetto.

L'obiettivo moderno C crea una variabile di istanza per te implicitamente quando si dichiarano le proprietà. Si dice spesso che tali proprietà sono supportate da variabili di istanza.

Normalmente non vi è alcun motivo per implementare in modo esplicito setter e getter, poiché il compilatore fa questo per voi dietro le quinte.(In una stessa maniera, ma crea anche quelle variabili di istanza per voi)

Ma se si desidera implementare setter in modo esplicito, è necessario impostare la variabile di istanza nel setter, non chiamare il setter in sé ancora una volta (tramite dot convenzione di notazione) come ho spiegato sopra.

Le variabili di istanza create in modo implicito hanno una convenzione di denominazione con trattino basso come prefisso. Nel tuo caso è

_firstName 

Quando si dichiara una proprietà chiamata firstName, si ottiene anche un'istanza variabile
_firstName

È setter dovrebbe assomigliare a questa

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

E Getter

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

Capisco cosa intendi. Grazie per la spiegazione. – ReverseEffect