2010-05-17 3 views
9

Je travaille sur une application qui utilise les données de base comme backend pour la gestion des enregistrements SQLite. J'ai tout travaillé avec des chaînes et des nombres, mais j'ai juste essayé d'ajouter des champs BOOL et je n'arrive pas à faire fonctionner les choses.Configuration des données de base et de BOOL

Dans le .xcdatamodel, j'ai ajouté un champ à mon objet appelé isCurrentlyForSale qui n'est pas optionnel, pas transitoire, et non indexé. Le type de l'attribut est défini sur Boolean avec la valeur par défaut NO.

Lorsque j'ai créé les fichiers de classe à partir du modèle de données, le code boilerplate ajouté pour cette propriété dans l'en-tête .h était:

@property (nonatomic, retain) NSNumber * isCurrentlyForSale; 

avec le

@dynamic isCurrentlyForSale; 

dans le .m fichier d'implémentation.

J'ai toujours travaillé avec des booléens comme de simples BOOL. J'ai lu que je pourrais utiliser les méthodes numberWithBool et boolValue de NSNumber, mais cela semble être un énorme lot de code supplémentaire pour quelque chose d'aussi simple.

Le @property dans l'en-tête peut-il être changé en simple BOOL? Si oui, y a-t-il quelque chose à surveiller?

Merci -John

Répondre

2

réponse simple: Non, vous ne pouvez pas changer la déclaration @property pour retourner un BOOL.

Vous pouvez cependant écrire des enveloppes simples. Je renomme l'attribut à currentlyForSale (ce qui signifie qu'il génère currentlyForSale et setCurrentlyForSale:), puis écrire deux emballages:

- (BOOL) isCurrentlyForSale { 
    return [[self currentlyForSale] boolValue]; 
} 

- (void) setIsCurrentlyForSale:(BOOL)forSale { 
    [self setCurrentlyForSale:[NSNumber numberWithBool:forSale]]; 
} 
+0

Un setter ou une propriété doit avoir "is" dedans. C'est pourquoi '@ property' a le paramètre' getter = '. Et oui, vous pouvez faire en sorte que '@ property' soit changé en BOOL en utilisant les accesseurs primitifs qui font partie des Core Data. –

+0

@Marcus Oui, je sais que les setters ne devraient pas avoir 'Is' dedans, mais je l'ai mis parce que' setCurrentlyForSale: 'était déjà pris par CD (et je suis conscient de' getter = 'et' setter = '. Et dites-vous que vous pouvez simplement changer le 'NSNumber *' à 'BOOL' dans l'en-tête et ça va marcher?Cela me surprendrait * définitivement *. –

30

Alors que la réponse de Dave DeLong est proche, vous pouvez réellement faire cela sans avoir à changer le nom de la propriété.

Vous peut changer la propriété pour retourner un BOOL mais vous devez alors écrire les accesseurs par la main et ils sont un peu différent de ce que Dave a dans sa réponse.

d'abord votre @property doit être définie comme:

@property (nonatomic, getter=isCurrentlyForSale) BOOL currentlyForSale; 

Ensuite, dans votre dossier de mise en œuvre, au lieu de déclarer une propriété @dynamic, créer les accesseurs directement.

- (BOOL)isCurrentlyForSale 
{ 
    [self willAccessValueForKey:@"currentlyForSale"]; 
    BOOL b = [[self primitiveValueForKey:@"currentlyForSale"] boolValue]; 
    [self didAccessValueForKey:@"currentlyForSale"]; 
    return b; 
} 

- (void)setCurrentlyForSale:(BOOL)b 
{ 
    [self willChangeValueForKey:@"currentlyForSale"]; 
    [self setPrimitiveValue:[NSNumber numberWithBool:b] forKey:@"currentlyForSale"]; 
    [self didChangeValueForKey:@"currentlyForSale"]; 
} 

Avec ces accesseurs votre objet se chargera de la boxe pour vous et vous pouvez y accéder en tant que valeur primitive. En outre, un setter commençant par setIs n'est pas une bonne idée, d'où la suppression de l'exemple de code.

+0

+1 ah, je comprends ce que vous dites maintenant. Je pensais que vous étiez en train de suggérer que vous pouviez changer le '@ property' en' BOOL' et ne pas implémenter des méthodes personnalisées. En aparté, le setter est légèrement incorrect. Le '(will | did) ChangeValueForKey:' ne devrait être invoqué que si la nouvelle valeur est réellement différente (c'est-à-dire que vous avez besoin d'une instruction if). –

+0

Excellent exemple et explication - merci Marcus! –

+0

La seule chose que j'ajouterais, c'est que j'aime utiliser les constantes NSString pour les noms de touches, cela évite d'avoir à résoudre des erreurs typographiques plus tard. 'NSString * const ActuellementForSale = @" currentlyForSale ";' – Eric

Questions connexes