Vous devrez créer des accesseurs personnalisés si vous souhaitez limiter les valeurs à une énumération. Donc, vous déclarez d'abord une énumération, comme ceci:
typedef enum {
kPaymentFrequencyOneOff = 0,
kPaymentFrequencyYearly = 1,
kPaymentFrequencyMonthly = 2,
kPaymentFrequencyWeekly = 3
} PaymentFrequency;
Ensuite, déclarez les getters et les setters pour votre propriété. C'est une mauvaise idée de remplacer ceux existants, car les accesseurs standard attendent un objet NSNumber plutôt qu'un type scalaire, et vous rencontrerez des problèmes si quelque chose dans les liaisons ou les systèmes KVO essaie d'accéder à votre valeur.
- (PaymentFrequency)itemTypeRaw {
return (PaymentFrequency)[[self itemType] intValue];
}
- (void)setItemTypeRaw:(PaymentFrequency)type {
[self setItemType:[NSNumber numberWithInt:type]];
}
Enfin, vous devez implémenter + keyPathsForValuesAffecting<Key>
afin d'obtenir des notifications KVO pour itemTypeRaw lorsque itemType change.
+ (NSSet *)keyPathsForValuesAffectingItemTypeRaw {
return [NSSet setWithObject:@"itemType"];
}
enum
s?int16_t
et vous êtes prêt.Vous pouvez faire de cette façon, de manière plus simple:
Et dans votre modèle, défini
itemType
comme un nombre 16 bits. Terminé. Aucun code supplémentaire nécessaire. Mettez juste votre habitudeSi vous utilisez Xcode pour créer votre
NSManagedObject
sous-classe, assurez-vous que le paramètre " Utiliser les propriétés scalaires pour les types de données primitifs " est coché.la source
retain
est lié à la gestion de la mémoire, pas à savoir si elle est stockée dans la base de données ou non.Une approche alternative que j'envisage est de ne pas déclarer du tout une énumération, mais plutôt de déclarer les valeurs en tant que méthodes de catégorie sur NSNumber.
la source
Si vous utilisez mogenerator, jetez un œil à ceci: https://github.com/rentzsch/mogenerator/wiki/Using-enums-as-types . Vous pouvez avoir un attribut Integer 16 appelé
itemType
, avec uneattributeValueScalarType
valeur deItem
dans les informations utilisateur. Ensuite, dans les informations utilisateur de votre entité, définissezadditionalHeaderFileName
le nom de l'en-tête dans lequel l'Item
énumération est définie. Lors de la génération de vos fichiers d'en-tête, mogenerator attribuera automatiquement leItem
type à la propriété .la source
J'ai défini le type d'attribut comme un entier de 16 bits, puis j'utilise ceci:
...
la source
Étant donné que les énumérations sont soutenues par un court standard, vous ne pouvez pas non plus utiliser l'encapsuleur NSNumber et définir la propriété directement en tant que valeur scalaire. Assurez-vous de définir le type de données dans le modèle de données de base sur «Integer 32».
MyEntity.h
Ailleurs dans le code
Ou analyse à partir d'une chaîne JSON ou chargement à partir d'un fichier
la source
J'ai beaucoup fait cela et je trouve le formulaire suivant utile:
Dans ce cas, l'énumération est assez simple:
et l'appelle pédant, mais j'utilise des énumérations pour les noms de champs, comme ceci:
Comme cela peut devenir laborieux pour les modèles de données complexes, j'ai écrit un générateur de code qui consomme le MOM / les entités pour cracher tous les mappages. Mes entrées finissent par être un dictionnaire du type Table / Row au type Enum. Pendant que j'y étais, j'ai également généré du code de sérialisation JSON. J'ai fait cela pour des modèles très complexes et cela s'est avéré être un gain de temps considérable.
la source
Le code collé ci-dessous fonctionne pour moi, et je l'ai ajouté comme exemple de travail complet. J'aimerais entendre des opinions sur cette approche, car je prévois de l'utiliser largement dans mes applications.
J'ai laissé le @dynamic en place, car il est ensuite satisfait par le getter / setter nommé dans la propriété.
Selon la réponse d'iKenndac, je n'ai pas remplacé les noms de getter / setter par défaut.
J'ai inclus une vérification de plage via un NSAssert sur les valeurs valides typedef.
J'ai également ajouté une méthode pour obtenir une valeur de chaîne pour le typedef donné.
Je préfixe les constantes avec "c" plutôt que "k". Je connais le raisonnement derrière "k" (origines mathématiques, historique), mais j'ai l'impression de lire du code ESL avec, donc j'utilise "c". Juste une chose personnelle.
Il y a une question similaire ici: typedef comme type de données Core
J'apprécierais toute contribution sur cette approche.
la source
Solution pour les classes générées automatiquement
à partir du générateur de code de Xcode (ios 10 et supérieur)
Si vous créez une entité nommée "YourClass", Xcode choisira automatiquement "Définition de classe" comme type de Codegen par défaut dans "Data Model Inspector". cela générera des classes ci-dessous:
Version Swift:
Version Objective-C:
Nous choisirons "Catégorie / Extension" dans l'option Codegen au lieu de "Définition de classe" dans Xcode.
Maintenant, si nous voulons ajouter une énumération, allez créer une autre extension pour votre classe générée automatiquement et ajoutez vos définitions d'énumération ici comme ci-dessous:
Désormais, vous pouvez créer des accesseurs personnalisés si vous souhaitez limiter les valeurs à une énumération. Veuillez vérifier la réponse acceptée par le propriétaire de la question . Ou vous pouvez convertir vos énumérations pendant que vous les définissez avec une méthode de conversion explicite en utilisant l'opérateur de cast comme ci-dessous:
Vérifiez également
Génération automatique de sous-classes Xcode
la source