핵심 데이터를 사용하여 열거형을 구현하는 가장 좋은 방법
엔티티에 형식 속성을 할당할 수 있도록 코어 데이터 엔티티를 열거값에 바인딩하는 가장 좋은 방법은 무엇입니까?다시 말해, 나는 그 존재를 가지고 있습니다.ItemitemType내가 열거형에 묶이고 싶은 재산, 이 일을 진행하는 가장 좋은 방법은 무엇입니까?
값을 열거형으로 제한하려면 사용자 지정 접근자를 만들어야 합니다.먼저 다음과 같이 열거형을 선언합니다.
typedef enum {
kPaymentFrequencyOneOff = 0,
kPaymentFrequencyYearly = 1,
kPaymentFrequencyMonthly = 2,
kPaymentFrequencyWeekly = 3
} PaymentFrequency;
그런 다음 재산에 대한 게터와 세터를 선언합니다.표준 접근자는 스칼라 유형이 아닌 NSNumber 개체를 예상하기 때문에 기존 접근자를 재정의하는 것은 좋지 않습니다. 바인딩이나 KBO 시스템에서 값에 액세스하는 것이 있으면 문제가 발생합니다.
- (PaymentFrequency)itemTypeRaw {
return (PaymentFrequency)[[self itemType] intValue];
}
- (void)setItemTypeRaw:(PaymentFrequency)type {
[self setItemType:[NSNumber numberWithInt:type]];
}
은 마막으로구, 을야합니다해현을 실행해야 .+ keyPathsForValuesAffecting<Key>에 대한 됩니다.항목 ▁changestypeType이변경되면 합니다.유형이 변경됩니다.
+ (NSSet *)keyPathsForValuesAffectingItemTypeRaw {
return [NSSet setWithObject:@"itemType"];
}
이 방법을 사용하면 훨씬 간단합니다.
typedef enum Types_e : int16_t {
TypeA = 0,
TypeB = 1,
} Types_t;
@property (nonatomic) Types_t itemType;
그리고 당신의 모델에서, 세트는itemType16비트 숫자가 됩니다.다됐니다습▁. 추가 코드가 필요하지 않습니다.그냥 평소대로 넣으세요.
@dynamic itemType;
Xcode를 Xcode를 합니다.NSManagedObject하위 클래스, "기본 데이터 유형에 스칼라 속성 사용" 설정이 선택되어 있는지 확인합니다.
제가 고려하고 있는 대안적인 접근법은 열거형을 전혀 선언하지 않고 대신 NSNumber의 범주 메소드로 값을 선언하는 것입니다.
모제너레이터를 사용하는 경우 https://github.com/rentzsch/mogenerator/wiki/Using-enums-as-types 을 참조하십시오.다음과 같은 정수 16 특성을 가질 수 있습니다.itemTypeattributeValueScalarType의 값Item사용자 정보에 있습니다.그런 다음 엔티티의 사용자 정보에서 다음을 설정합니다.additionalHeaderFileName, 의이름은이 합니다.Item열거형은 에 정의되어 있습니다.헤더 파일을 생성할 때, 모제너레이터는 자동으로 속성이 다음과 같이 되도록 할 것입니다.Item활자를
속성 유형을 16비트 정수로 설정한 다음 다음을 사용합니다.
#import <CoreData/CoreData.h>
enum {
LDDirtyTypeRecord = 0,
LDDirtyTypeAttachment
};
typedef int16_t LDDirtyType;
enum {
LDDirtyActionInsert = 0,
LDDirtyActionDelete
};
typedef int16_t LDDirtyAction;
@interface LDDirty : NSManagedObject
@property (nonatomic, strong) NSString* identifier;
@property (nonatomic) LDDirtyType type;
@property (nonatomic) LDDirtyAction action;
@end
...
#import "LDDirty.h"
@implementation LDDirty
@dynamic identifier;
@dynamic type;
@dynamic action;
@end
열거형은 표준 단락으로 지원되므로 NSNumber 래퍼를 사용할 수 없으며 속성을 스칼라 값으로 직접 설정할 수도 없습니다.코어 데이터 모델의 데이터 유형을 "Integer 32"로 설정해야 합니다.
나의 실체.
typedef enum {
kEnumThing, /* 0 is implied */
kEnumWidget, /* 1 is implied */
} MyThingAMaBobs;
@interface myEntity : NSManagedObject
@property (nonatomic) int32_t coreDataEnumStorage;
코드의 다른 부분
myEntityInstance.coreDataEnumStorage = kEnumThing;
또는 JSON 문자열에서 구문 분석 또는 파일에서 로드
myEntityInstance.coreDataEnumStorage = [myStringOfAnInteger intValue];
저는 이 작업을 많이 수행했으며 다음 양식이 유용하다는 것을 알게 되었습니다.
// accountType
public var account:AccountType {
get {
willAccessValueForKey(Field.Account.rawValue)
defer { didAccessValueForKey(Field.Account.rawValue) }
return primitiveAccountType.flatMap { AccountType(rawValue: $0) } ?? .New }
set {
willChangeValueForKey(Field.Account.rawValue)
defer { didChangeValueForKey(Field.Account.rawValue) }
primitiveAccountType = newValue.rawValue }}
@NSManaged private var primitiveAccountType: String?
이 경우 열거형은 매우 간단합니다.
public enum AccountType: String {
case New = "new"
case Registered = "full"
}
현학적이라고 부르지만 필드 이름에는 다음과 같은 열거형을 사용합니다.
public enum Field:String {
case Account = "account"
}
복잡한 데이터 모델에서는 이것이 힘들 수 있기 때문에, 저는 모든 매핑을 뱉어내기 위해 MOM/엔티티를 소비하는 코드 생성기를 작성했습니다.입력한 내용은 테이블/행에서 열거형에 이르는 사전이 됩니다.제가 있는 동안 JSON 직렬화 코드도 생성했습니다.저는 매우 복잡한 모델을 위해 이 작업을 수행해 보았는데, 시간을 크게 절약할 수 있었습니다.
아래에 붙여넣은 코드는 저에게 효과가 있고, 저는 그것을 완전한 작동 예로 추가했습니다.앱 전반에 걸쳐 광범위하게 사용할 계획이기 때문에 이 접근 방식에 대한 의견을 듣고 싶습니다.
@dynamic은 속성에 이름이 지정된 getter/setter에 의해 충족되므로 그대로 둡니다.
iKenndac의 답변에 따르면 기본 getter/setter 이름을 재정의하지 않았습니다.
NSA sert를 통한 범위 검사를 typedef 유효값에 포함시켰습니다.
주어진 typeef의 문자열 값을 구하는 방법도 추가했습니다.
저는 상수 앞에 "k"가 아닌 "c"를 붙입니다.저는 "k"(수학 기원, 역사) 뒤에 있는 추론을 알고 있지만, 그것으로 ESL 코드를 읽는 것 같아서 "c"를 사용합니다.그냥 개인적인 일입니다.
여기에도 비슷한 질문이 있습니다. 핵심 데이터 유형으로 typdef를 입력하십시오.
이 접근법에 대한 의견을 주시면 감사하겠습니다.
Word.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
typedef enum {
cPresent = 0,
cFuturProche = 1,
cPasseCompose = 2,
cImparfait = 3,
cFuturSimple = 4,
cImperatif = 5
} TenseTypeEnum;
@class Word;
@interface Word : NSManagedObject
@property (nonatomic, retain) NSString * word;
@property (nonatomic, getter = tenseRaw, setter = setTenseRaw:) TenseTypeEnum tense;
// custom getter & setter methods
-(void)setTenseRaw:(TenseTypeEnum)newValue;
-(TenseTypeEnum)tenseRaw;
- (NSString *)textForTenseType:(TenseTypeEnum)tenseType;
@end
Word.m
#import "Word.h"
@implementation Word
@dynamic word;
@dynamic tense;
// custom getter & setter methods
-(void)setTenseRaw:(TenseTypeEnum)newValue
{
NSNumber *numberValue = [NSNumber numberWithInt:newValue];
[self willChangeValueForKey:@"tense"];
[self setPrimitiveValue:numberValue forKey:@"tense"];
[self didChangeValueForKey:@"tense"];
}
-(TenseTypeEnum)tenseRaw
{
[self willAccessValueForKey:@"tense"];
NSNumber *numberValue = [self primitiveValueForKey:@"tense"];
[self didAccessValueForKey:@"tense"];
int intValue = [numberValue intValue];
NSAssert(intValue >= 0 && intValue <= 5, @"unsupported tense type");
return (TenseTypeEnum) intValue;
}
- (NSString *)textForTenseType:(TenseTypeEnum)tenseType
{
NSString *tenseText = [[NSString alloc] init];
switch(tenseType){
case cPresent:
tenseText = @"présent";
break;
case cFuturProche:
tenseText = @"futur proche";
break;
case cPasseCompose:
tenseText = @"passé composé";
break;
case cImparfait:
tenseText = @"imparfait";
break;
case cFuturSimple:
tenseText = @"futur simple";
break;
case cImperatif:
tenseText = @"impératif";
break;
}
return tenseText;
}
@end
자동 생성 클래스에 대한 솔루션
Xcode의 코드 생성기(ios 10 이상)에서
만약 당신이 "당신의 클래스"라는 엔터티를 만든다면, Xcode는 자동으로 "데이터 모델 검사기"에서 "클래스 정의"를 기본 코드젠 유형으로 선택합니다.아래의 클래스를 생성합니다.
빠른 버전:
// YourClass+CoreDataClass.swift
@objc(YourClass)
public class YourClass: NSManagedObject {
}
목표-C 버전:
// YourClass+CoreDataClass.h
@interface YourClass : NSManagedObject
@end
#import "YourClass+CoreDataProperties.h"
// YourClass+CoreDataClass.m
#import "YourClass+CoreDataClass.h"
@implementation YourClass
@end
Xcode의 "Class Definition" 대신 Codegen 옵션에서 "Category/Extension"을 선택합니다.
이제 열거형을 추가하려면 자동 생성된 클래스에 대해 다른 확장자를 만들고 다음과 같이 열거형 정의를 여기에 추가하십시오.
// YourClass+Extension.h
#import "YourClass+CoreDataClass.h" // That was the trick for me!
@interface YourClass (Extension)
@end
// YourClass+Extension.m
#import "YourClass+Extension.h"
@implementation YourClass (Extension)
typedef NS_ENUM(int16_t, YourEnumType) {
YourEnumTypeStarted,
YourEnumTypeDone,
YourEnumTypePaused,
YourEnumTypeInternetConnectionError,
YourEnumTypeFailed
};
@end
이제 값을 열거형으로 제한하려는 경우 사용자 지정 접근자를 만들 수 있습니다.질문 소유자가 수락한 답변을 확인하십시오.또는 아래와 같이 캐스트 연산자를 사용하여 명시적 변환 방법으로 설정하는 동안 열거형을 변환할 수 있습니다.
model.yourEnumProperty = (int16_t)YourEnumTypeStarted;
Xcode 자동 하위 클래스 생성
Xcode는 이제 모델링 도구에서 NSManagedObject 하위 클래스의 자동 생성을 지원합니다.엔티티 검사기에서 다음을 수행합니다.
수동/없음이 기본값이며 이전 동작입니다. 이 경우 사용자 자신의 하위 클래스를 구현하거나 NSManagedObject를 사용해야 합니다.Category/Extension은 ClassName+CoreDataGeneratedProperties와 같은 파일에 클래스 확장자를 생성합니다.기본 클래스를 선언/구현해야 합니다(Obj-C의 경우 헤더를 통해 확장에서 ClassName.h라는 이름을 가져올 수 있습니다).ClassDefinition은 ClassName+CoreDataClass와 같은 하위 클래스 파일과 범주/확장에 대해 생성된 파일을 생성합니다.생성된 파일은 파생 데이터에 저장되고 모델이 저장된 후 첫 번째 빌드에서 다시 빌드됩니다.또한 Xcode에 의해 색인화되므로 참조를 명령으로 클릭하고 파일 이름으로 빠르게 여는 것이 작동합니다.
언급URL : https://stackoverflow.com/questions/1624297/best-way-to-implement-enums-with-core-data
'programing' 카테고리의 다른 글
| C 및 C++ 함수 서명에 사용되는 휴대용 USED 매개 변수 매크로 (0) | 2023.07.16 |
|---|---|
| SQL Server에서 커서를 사용하는 것이 잘못된 관행으로 간주되는 이유는 무엇입니까? (0) | 2023.07.16 |
| 기본적으로 푸시하지 않고 jib-maven-plugin을 사용하여 도커 이미지를 구축하는 방법은 무엇입니까? (0) | 2023.07.16 |
| Oracle current_date 또는 sysdate(시간, 분, 초 없음) (0) | 2023.07.16 |
| 하나의 열에 동일한 값이 있을 때 sql 쿼리를 원합니다. (0) | 2023.07.16 |