2010-05-30 9 views
52

Ho impostato uno dei miei attributi di dati principali come booleano. Ora, ho bisogno di impostarlo, ma XCode continua a dirmi che potrebbe non rispondere a setUseGPS.iPhone: Salva booleano in Core Data

[ride setUseGPS: useGPS.on]; 

Qual è il metodo per impostare un valore booleano nei dati di base? Tutti i miei altri attributi sono impostati in questo modo e funzionano alla grande. Quindi, non sono sicuro del motivo per cui un booleano non funziona per essere impostato in questo modo?

+0

Partenza NSNumber –

risposta

131

I dati di base "non ha" un tipo booleano (lo fa, ma è un numero NSN).

Quindi impostare l'equivalente di useGPS = YES.

[entity setUseGPS:[NSNumber numberWithBool:YES]]; 

E viceversa:

BOOL isGPSOn = [[entity useGPS] boolValue]; 

Aggiornamento: Come sottolineato da SKG, di valori letterali in scopo principale-C ora si può fare in modo più semplice:

[entity setUseGPS:@YES]; 

BOOL isGPSOn = entity.useGPS.boolValue; 
+9

È possibile impostare i valori... in questo modo anche: 'object.isGPSOn = @YES;' – guptron

+0

Apparentemente, posso effettivamente vedere il tipo booleano nel menu a discesa quando si crea un nuovo attributo nell'editor di dati di base. Che dire di questo? –

0

La "correzione" per questo (IMHO, è un bug nell'SDK di Apple) è aggiungere il seguente codice alla classe generata da CoreData. NB: se fate questo in una categoria, in un file separato, quindi non c'è bisogno di ri-copia/incolla ogni volta che si rigenerare le classi CoreData all'interno Xcode

- (BOOL)useGPS 
{ 
    [self willAccessValueForKey:@"useGPS"]; 
    BOOL myuseGPS = [[self primitiveUseGPS] boolValue]; 
    [self didAccessValueForKey:@"useGPS"]; 
    return myuseGPS; 
} 

- (void)setUseGPS:(BOOL)newValue 
{ 
    [self willChangeValueForKey:@"useGPS"]; 
    [self setPrimitiveUseGPS:[NSNumber numberWithBool:newValue]]; 
    [self didChangeValueForKey:@"useGPS"]; 
} 
+0

Questo porta a tipi in conflitto quando compilo. Devo modificare i tipi delle proprietà NSNumber esistenti? –

+0

@Daniel Wood: non modificare i tipi esistenti: CoreData richiede che siano NSNumber. gli avvisi di compilazione sono fastidiosi: la soluzione facile è rinominare i due metodi precedenti in "useGPSAsBool" e "setUseGPSAsBool". NB: puoi ancora accedere alla proprietà, solo che ora è chiamata "GPSAsBool", ad es. "if (myCoreDataObject.GPSAsBool)" – Adam

+0

Dopo aver letto quanto segue nei documenti ho deciso di non preoccuparmi di nulla di tutto questo e di convertire da NSNumber nel mio codice: "I vantaggi di consentire a Core Data di gestire il proprio storage di solito superano qualsiasi vantaggio di interagire direttamente con i valori scalari "http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html –

18

Come approccio alternativo al risposta accettata, si può semplicemente cambiare la tipizzazione da un NSNumber * ad un BOOL nella definizione dell'interfaccia oggetto gestito, come ad esempio:

@property (nonatomic) BOOL useGPS; // Notice that the 'retain' is also removed as we're now dealing with a scalar rather than an NSObject 

Vari approcci alternativi sono discussi here, ma Chris Hanson 's risposta è stata più illuminanti per me , in particolare:

Se si dispone di un attributo numerico (tra cui un attributo booleano) che è necessario, è possibile basta digitare come una scalari, invece, e Core Data farà la cosa giusta:

@property (nonatomic) BOOL isDone;

Anche se l'attributo è facoltativo, funzionerà ancora - sarà solo conflate "non presente" con "falso".

e per un'implementazione di cacao più in linea:

Un altra cosa si potrebbe desiderare di fare è il nome della proprietà "fatto" e solo specificare il getter come "isDone." Questa è la la solita convenzione di denominazione del cacao:

@property (nonatomico, getter = isDone) BOOL done;

Quindi è possibile scrivere "if (item.done) { ...}" o "item.fatto = no;" e il compilatore sarà ancora generare -isDone per accessi della proprietà

Grazie Chris, e spero che questo aiuta qualcuno

+1

Sto vedendo un crash su iOS 4.x quando provo questo metodo. Ecco il messaggio: "Proprietà" bar "è un tipo scalare sulla classe" Foo ". Impossibile generare un metodo getter per questo". Ho provato a impostare il tipo di attributo su Boolean nel modello Core Data, e ho anche provato Intero 16. Ottengo lo stesso crash in entrambi i casi. Mi sto perdendo qualcosa? Forse tornerò a usare NSNumber. –

+2

Per quanto ne so, questo non funziona sulle sottoclassi NSManagedObject. – teh1