2010-05-30 12 views
52

He configurado uno de mis atributos principales de datos como booleano. Ahora, tengo que configurarlo, pero XCode sigue diciéndome que puede no responder a setUseGPS.iPhone: Guardar datos booleanos en Core Data

[ride setUseGPS: useGPS.on]; 

¿Cuál es el método para establecer un booleano en los datos básicos? Todos mis otros atributos están establecidos de esta manera, y funcionan muy bien. Entonces, ¿no estoy seguro de por qué un booleano no funciona para establecerse de esta manera?

+0

Salida NSNumber –

Respuesta

131

Datos básicos "no tiene" un tipo booleano (lo hace, pero es un NSNumber).

Para establecer el equivalente de useGPS = YES.

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

Y al revés:

BOOL isGPSOn = [[entity useGPS] boolValue]; 

Actualización: Como ha señalado SKG, con literales en Objetivo-C ahora se puede hacer de una manera más simple:

[entity setUseGPS:@YES]; 

BOOL isGPSOn = entity.useGPS.boolValue; 
+9

Puede ajustar los valores... así también: 'object.isGPSOn = @YES;' – guptron

+0

Aparentemente, puedo ver el tipo booleano en el menú desplegable al crear un nuevo atributo en el editor de datos básicos. ¿Qué pasa con eso? –

0

La "solución" para esto (en mi humilde opinión, es un error en el SDK de Apple) es agregar el siguiente código a su clase generada por CoreData. Nota: si hace esto en una categoría, en un archivo separado, entonces usted no tiene que volver a copiar/pegar cada vez que regenere las clases CoreData dentro de 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

Esto conduce a tipos conflictivos cuando compilo. ¿Debo cambiar los tipos de las propiedades NSNumber existentes? –

+0

@Daniel Wood - no cambie los tipos existentes: CoreData requiere que sean NSNumber. Las advertencias de compilación son irritantes. La solución más fácil es cambiar el nombre de los dos métodos anteriores para "usar GPSAsBool" y "setUseGPSAsBool". NB: aún puede acceder a la propiedad, solo que ahora se llama "GPSAsBool", p. "if (myCoreDataObject.GPSAsBool)" – Adam

+0

Después de leer lo siguiente en los documentos decidí no molestarme con nada de esto y simplemente convertir NSNumber en mi código: "Las ventajas de permitir que Core Data administre su propio almacenamiento generalmente superan cualquier ventaja de interactuar directamente con valores escalares "http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/Articles/cdNSAttributes.html –

18

Como un enfoque alternativo a la respuesta aceptada, sólo tiene que cambiar la tipificación de un NSNumber * a un BOOL en la definición de interfaz objeto administrado, tales como:

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

diversos enfoques alternativos se discuten here, pero Chris Hanson 's respuesta fue más esclarecedor para mí , especialmente:

Si usted tiene un atributo numérico (incluyendo un atributo booleano) eso es necesaria, sólo puede escribir como un escalar lugar, y datos básicos hará lo correcto:

@property (no atómica) BOOL isDone;

Incluso si el atributo es opcional, que todavía funcionará - solo va a combinar "no presente" con "falso".

y para una aplicación Cocoa más alineado:

Otra cosa es posible que desee hacer es el nombre de la propiedad "hecho" y justo especifique el comprador como "isDone." Eso es la convención de nomenclatura de Cacao habitual:

@property (nonatomic, getter = isDone) BOOL hecho;

Luego puede escribir "if (item.done) { ...}" o "item.hecho = NO;" y el compilador todavía generará -isDone para los accesos de la propiedad

Gracias Chris, y espero que esto ayude a alguien

+1

Estoy viendo un bloqueo en iOS 4.x cuando pruebo este método. Aquí está el mensaje: "Propiedad 'barra' es un tipo escalar en la clase 'Foo'. No se puede generar un método getter para él". Intenté configurar el tipo de atributo como booleano en el modelo de Datos centrales, y también probé el Entero 16. Obtuve el mismo bloqueo de cualquier manera. ¿Me estoy perdiendo de algo? Tal vez regrese a usar NSNumber. –

+2

Hasta donde yo sé, esto no funciona en las subclases NSManagedObject. – teh1

Cuestiones relacionadas