[iphone] 핵심 데이터로 Enum을 구현하는 가장 좋은 방법

엔터티에 유형 속성을 할당 할 수 있도록 핵심 데이터 엔터티를 열거 형 값에 바인딩하는 가장 좋은 방법은 무엇입니까? 즉, 내가이라는 실체가 ItemitemType내가 열거에 구속하려는 속성을, 이것에 대해가는 가장 좋은 방법은 무엇인가.



답변

값을 열거 형으로 제한하려면 사용자 지정 접근자를 만들어야합니다. 따라서 먼저 다음과 같이 열거 형을 선언합니다.

typedef enum {
    kPaymentFrequencyOneOff = 0,
    kPaymentFrequencyYearly = 1,
    kPaymentFrequencyMonthly = 2,
    kPaymentFrequencyWeekly = 3
} PaymentFrequency;

그런 다음 속성에 대한 getter 및 setter를 선언하십시오. 표준 접근자가 스칼라 유형이 아닌 NSNumber 객체를 기대하고 바인딩 또는 KVO 시스템의 어떤 것이 든 값에 액세스하려고하면 문제가 발생하기 때문에 기존 접근자를 재정의하는 것은 나쁜 생각입니다.

- (PaymentFrequency)itemTypeRaw {
    return (PaymentFrequency)[[self itemType] intValue];
}

- (void)setItemTypeRaw:(PaymentFrequency)type {
    [self setItemType:[NSNumber numberWithInt:type]];
}

마지막으로 + keyPathsForValuesAffecting<Key>itemType이 변경 될 때 itemTypeRaw에 대한 KVO 알림을 받도록 구현 해야합니다.

+ (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를 사용하여 NSManagedObject하위 클래스를 만드는 경우 ” 기본 데이터 유형에 스칼라 속성 사용 “설정이 선택되어 있는지 확인하십시오.


답변

내가 고려하고있는 다른 접근 방식은 열거 형을 전혀 선언하지 않고 대신 NSNumber의 범주 메서드로 값을 선언하는 것입니다.


답변

mogenerator를 사용하는 경우 https://github.com/rentzsch/mogenerator/wiki/Using-enums-as-types를 살펴보십시오 . 당신은라는 정수 (16) 속성을 가질 수 itemTypeA를, attributeValueScalarType의 값 Item은 사용자 정보에 있습니다. 그런 다음 엔터티의 사용자 정보 additionalHeaderFileName에서 Item열거 형이 정의 된 헤더의 이름으로 설정 합니다 . 헤더 파일을 생성 할 때 mogenerator는 자동으로 속성에 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


답변

열거 형은 표준 short로 뒷받침되기 때문에 NSNumber 래퍼를 사용하지 않고 속성을 스칼라 값으로 직접 설정할 수도 있습니다. 핵심 데이터 모델의 데이터 유형을 “Integer 32″로 설정해야합니다.

MyEntity.h

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 / 엔티티를 사용하는 코드 생성기를 작성했습니다. 내 입력은 Table / Row에서 Enum 유형으로의 사전이됩니다. 거기에있는 동안 JSON 직렬화 코드도 생성했습니다. 매우 복잡한 모델에 대해이 작업을 수행했으며 시간을 크게 절약 할 수있었습니다.