2010-07-12 12 views
119

Recentemente ho provato a compilare un progetto Xcode più vecchio (che ha usato per compilare bene), e ora sto vedendo un sacco di errori di questa forma:errore: scrivibile proprietà atomica non può abbinare un setter/getter sintetizzato con un setter/getter definito dall'utente

error: writable atomic property 'someProperty' cannot pair a synthesized setter/getter with a user defined setter/getter

il modello di codice che causa questi errori sempre assomiglia a questo:

// Interface: 

@property (retain) NSObject * someProperty; 

// Implementation: 

@synthesize someProperty; // to provide the getter 
- (void)setSomeProperty:(NSObject *)newValue 
{ 
    //.. 
} 

posso capire perché è stato generato l'errore. Dico al compilatore di sintetizzare i miei accessors di proprietà (sia getter che setter), e subito dopo sovrascrivo manualmente il setter. Quel codice ha sempre un po 'spento.

Quindi, qual è il modo corretto di fare questo? Se uso @dynamic anziché @synthesize, dovrò scrivere anche il getter. E 'l'unica possibilità?

+0

Questo succede solo con le proprietà 'atomiche'? In caso di proprietà atomiche potrebbe essere una buona idea mantenere la coppia getter/setter in sincronia rispetto alla strategia di blocco. Questo è difficile se una parte viene sintetizzata mentre l'altra è un codice personalizzato. –

+0

Certamente se ne va la proprietà non anatomica. Interessante. Non avevo nemmeno pensato al problema di sincronizzazione. –

+0

Ho visitato questo argomento per trovare una soluzione a questo problema esatto. Non voglio davvero scrivere un getter e un setter da solo. Oh bene ... –

risposta

208

Ho avuto lo stesso problema e dopo aver fatto un po 'di ricerca, qui è la mia conclusione su questo problema:

Il compilatore avvisa della presenza di un @property che sono stati dichiarati come atomico (cioè omettendo la parola chiave nonatomic), tuttavia fornisci un'implementazione incompleta di come sincronizzare l'accesso a quella proprietà.

Per fare questo avvertimento scomparire:

Se si dichiara una @property essere atomica quindi eseguire una delle seguenti operazioni:

  • uso @dynamic o;
  • utilizzare @synthesize e mantenere il setter sintetizzato e getter o;
  • fornire un'implementazione manuale di sia setter e getter (senza utilizzare una delle direttive di cui sopra).

Se si dichiara la @property con (nonatomic) allora si può mescolare le implementazioni manuali e sintetizzati di getter e setter.

Update: Una nota sulla proprietà Auto-Sintesi

Come di LLVM 4.0, clang fornisce auto-sintesi per le proprietà dichiarate che non sono @dynamic. Per impostazione predefinita, anche se si omette lo @synthesize, il compilatore fornirà i metodi getter e setter. Tuttavia, la regola per le proprietà atomiche è sempre lo stesso: o lasciare che il compilatore fornire sia il getter e setter, o implementare le sia te stesso!

+0

Mi dispiace per aver impiegato così tanto tempo a contrassegnare questo come accettato. Si è rivelato corretto al 100% e molto utile. –

+0

Grazie mille! –

+0

Grazie! "dichiarare la @property con (nonatomico)" – Nianliang

12

Questa domanda, tra gli altri successi migliori si ottiene dalla ricerca di "proprietà oggettiva C custom", non vengono aggiornati con informazioni su "setter =" o "getter =".

Quindi, per fornire ulteriori informazioni su questo argomento:

È possibile fornire la chiamata @property con il proprio metodo scrivendo

@property(setter = MySetterMethod:, getter = MyGetterMethod) 

Avviso i due punti per il metodo setter in dotazione.

Riferimento Apple documentation

EDIT: Io non sono molto sicuro di come le nuove modifiche alle proprietà di Objective-C (che sono molto più intelligenti ora) cambiano le risposte a questa domanda. Forse dovrebbe essere contrassegnato come non aggiornato.

+0

+1 Grazie per aver aggiunto questa eccellente informazione ':' –

+0

Ho trovato che l'impostazione del metodo setter non ha effettivamente rimosso l'avviso. per esempio. -> "@property (assign, setter = setDelegate :) id delegate;" In questo caso tutto quello che posso fare è aggiungere il mio getter o aggiungere la proprietà nonatomica, che non sono sicuro se dovrei, dato che sto impostando il delegato "atomicamente", non ha importanza avere la proprietà nonatomica , o così capisco. –

+0

Interessante, David. Qual è la "versione" di Objective-C in questo (suppongo che la versione XCode sarebbe più utile)? Non sono sicuro di quali siano le modifiche recenti a Objective-C, in particolare con iOS 6. –

12

È necessario implementare anche il getter. Esempio:

// Interface: 

@property (retain) NSObject * someProperty; 

// Implementation: 

- (void)setSomeProperty:(NSObject *)newValue 
{ 
    @synchronized (self) 
    { 
     // ... 
    } 
} 

- (NSObject *)someProperty 
{ 
    NSObject *ret = nil; 

    @synchronized (self) 
    { 
     ret = [[someProperty retain] autorelease]; 
    } 

    return ret; 
} 
Problemi correlati