web-dev-qa-db-fra.com

iPhone: enregistrez le booléen dans les données de base

J'ai configuré l'un de mes principaux attributs de données en tant que booléen. Maintenant, je dois le définir, mais XCode ne cesse de me dire qu'il peut ne pas répondre à setUseGPS.

[ride setUseGPS: useGPS.on];

Quelle est la méthode pour définir un booléen dans les données de base? Tous mes autres attributs sont définis de cette façon, et ils fonctionnent très bien. Donc, vous ne savez pas pourquoi un booléen ne fonctionne pas pour être défini de cette façon?

53
Nic Hubbard

Core Data "n'a pas" de type booléen (il en a, mais c'est un NSNumber).

Donc, pour définir l'équivalent de useGPS = YES.

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

Et l'inverse:

BOOL isGPSOn = [[entity useGPS] boolValue];

pdate: Comme l'a souligné SKG, avec les littéraux dans Objetive-C, vous pouvez maintenant le faire de manière plus simple:

[entity setUseGPS:@YES];

BOOL isGPSOn = entity.useGPS.boolValue;
133
RickiG

Comme approche alternative à la réponse acceptée, vous pouvez simplement changer le typage d'un NSNumber * à un BOOL dans la définition d'interface d'objet géré, comme:

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

Différentes approches alternatives sont discutées ici , mais Chris Hanson la réponse a été la plus éclairante pour moi, en particulier:

Si vous avez un attribut numérique (y compris un attribut booléen) requis, vous pouvez simplement le saisir comme un scalaire à la place, et Core Data fera la bonne chose:

@property (nonatomic) BOOL isDone;

Même si l'attribut est facultatif, cela fonctionnera toujours - il ne fera que confondre "non présent" avec "faux".

et pour une implémentation Cocoa plus alignée:

Une autre chose que vous voudrez peut-être faire est de nommer la propriété "done" et de spécifier simplement le getter comme "isDone". C'est la convention de dénomination Cocoa habituelle:

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

Ensuite, vous pouvez écrire "if (item.done) {...}" ou "item.done = NO;" et le compilateur générera toujours -isDone pour les accès à la propriété.

Merci Chris et j'espère que cela aide quelqu'un.

18
paulkmoore

Pour compléter la réponse @RickiG, la façon de créer un NSNumber à partir d'un Bool et vice-versa dans Swift (au moins depuis la v4.2) est:

let nsNumberFromBool = NSNumber(booleanLiteral: true) // or false
let boolFromNSNumber = nsNumberFromBool.boolValue
2

Le "correctif" pour cela (à mon humble avis, c'est un bogue dans le SDK d'Apple) est d'ajouter le code suivant à votre classe générée par CoreData. NB: si vous faites cela dans une catégorie, dans un fichier séparé, vous n'avez pas besoin de le recopier/coller à chaque fois que vous régénérez les classes CoreData dans 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
Adam