কোর ডেটা সহ এনামগুলি কার্যকর করার সর্বোত্তম উপায়


109

মূল ডেটা সত্তাগুলিকে এনাম মানগুলিতে বেঁধে রাখার সর্বোত্তম উপায় কী যাতে আমি সত্তাকে একটি ধরণের সম্পত্তি অর্পণ করতে সক্ষম হয়েছি? অন্য কথায়, আমার কাছে এমন Itemএকটি itemTypeসম্পত্তি রয়েছে যার সাথে আমি একটি এনামের সাথে আবদ্ধ হতে চাই, এটি সম্পর্কে সবচেয়ে ভাল উপায় কী property

উত্তর:


130

আপনি যদি এনামগুলিতে মানগুলি সীমাবদ্ধ রাখতে চান তবে আপনাকে কাস্টম অ্যাকসেসর তৈরি করতে হবে। সুতরাং, প্রথমে আপনি একটি এনাম ঘোষণা করবেন, এর মতো:

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

তারপরে, আপনার সম্পত্তির জন্য গেটার এবং সেটটারগুলি ঘোষণা করুন। বিদ্যমান উপস্থিতগুলিকে ওভাররাইড করা এটি একটি খারাপ ধারণা, যেহেতু স্ট্যান্ডার্ড অ্যাক্সেসররা স্কেলারের ধরণের পরিবর্তে কোনও এনএসবার্বার অবজেক্টের প্রত্যাশা করে এবং বাইন্ডিং বা কেভিও সিস্টেমগুলির মধ্যে কিছু আপনার চেষ্টা করে এবং আপনার মান অ্যাক্সেস করে তবে আপনি সমস্যার মধ্যে পড়ে যাবেন।

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

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

অবশেষে, আপনার প্রয়োগ করা উচিত + keyPathsForValuesAffecting<Key>যাতে আইটেমটাইপ পরিবর্তিত হলে আইটেম টাইপআর জন্য কেভিও বিজ্ঞপ্তি পান।

+ (NSSet *)keyPathsForValuesAffectingItemTypeRaw {
    return [NSSet setWithObject:@"itemType"];
}

2
আপনাকে ধন্যবাদ - খুব খারাপ কোর ডেটা এটিকে স্থানীয়ভাবে সমর্থন করে না। মানে: এক্সকোড ক্লাস ফাইল তৈরি করে, কেন নয় enum?
কনস্টান্টিনো জারোহাস

আপনি যদি আইটেমটি টাইপআর পর্যবেক্ষণ করতে চান তবে সর্বশেষ কোডটি। তবে, আপনি কেবল আইটেম টাইপআর এর পরিবর্তে আইটেম আইটেম টাইপটি পর্যবেক্ষণ করতে পারেন?
বেনামে হোয়াইট

2
এক্সকোড 4.5 দিয়ে আপনার এগুলির কোনও দরকার নেই। আমার উত্তর একবার দেখুন। আপনার কেবল এনামকে একটি হিসাবে int16_tনির্দিষ্ট করতে হবে এবং আপনি সেট হয়ে গেছেন ।
ড্যানিয়েল এগার্ট

79

আপনি সহজ উপায় এইভাবে করতে পারেন:

typedef enum Types_e : int16_t {
    TypeA = 0,
    TypeB = 1,
} Types_t;

@property (nonatomic) Types_t itemType;

এবং আপনার মডেলটিতে, itemType16 বিট নম্বর হিসাবে সেট করুন । সব শেষ. কোনও অতিরিক্ত কোডের প্রয়োজন নেই। শুধু আপনার যথারীতি রাখা

@dynamic itemType;

আপনি যদি আপনার NSManagedObjectসাবক্লাসটি তৈরি করতে এক্সকোড ব্যবহার করছেন তবে নিশ্চিত হয়ে নিন যে " আদিম ডেটা ধরণের জন্য স্কেলার বৈশিষ্ট্যগুলি ব্যবহার করুন " সেটিংস চেক করা আছে।


4
না, এর C ++ 11 এর সাথে কোনও সম্পর্ক নেই। এটি ওজেজির জন্য একটি নির্দিষ্ট অন্তর্নিহিত ধরণের সাথে গণনাগুলি সমর্থন করে ৩.৩ ঝাঁকুনির অংশ। সিএফ clang.llvm.org/docs/…
ড্যানিয়েল Eggert

6
প্রতিবার আপনি যখন মডেল ক্লাসটি পুনরায় তৈরি করবেন তখন আপনি এই কোডটি হারাবেন কীভাবে? আমি বিভাগগুলি ব্যবহার করে যাচ্ছি যাতে মূল ডোমেন সত্তাগুলি পুনরায় জেনারেট করা যায়।
রব

2
retainমেমরি ব্যবস্থাপনা সম্পর্কিত হয়, না কিনা এটা ডাটাবেসের বা না সংরক্ষণ করা হয়।
ড্যানিয়েল এগার্ট

2
আমি রবের সাথে একমত আমি চাই না যে এটি বার বার পুনরায় তৈরি করা উচিত। আমি বিভাগ পছন্দ।
কাইল রেডফারন

3
@ রব বিভাগগুলি এটি করার একটি উপায়, তবে পরিবর্তে আপনি মজেনেটর ব্যবহার করতে পারেন: github.com/rentzsch/mogenerator । মজেনেটর প্রতি সত্তায় 2 টি ক্লাস তৈরি করবে, যেখানে এক শ্রেণি সর্বদা ডেটা মডেল পরিবর্তনের উপর এবং অন্য সাবক্লাসগুলিতে কাস্টম স্টাফের জন্য শ্রেণিটি ওভাররাইট করা হয় না।
টেপমোনকি

22

একটি বিকল্প পদ্ধতির জন্য যা আমি বিবেচনা করছি তা হ'ল কোনও এনাম ঘোষণা করা নয়, পরিবর্তে মানগুলি এনএসএনম্বারে বিভাগ পদ্ধতি হিসাবে ঘোষণা করা।


মজাদার. এটি অবশ্যই করণীয় বলে মনে হচ্ছে।
মাইকেল গাইলর্ড

দারুণ বুদ্ধি! ডিবিতে টেবিল তৈরির চেয়ে অনেক সহজ, যদি না আপনার ডিবি কোনও ওয়েব পরিষেবা থেকে পূরণ না করা হয় তবে ডিবি টেবিলটি ব্যবহার করা সম্ভবত এটি সেরা!
TheLearner

6
এখানে একটি উদাহরণ রয়েছে: renovatioboy.wordpress.com/2011/10/06/…
আরডোচিঘ

আমি এটা পছন্দ করি. আমি আমার প্রকল্পে এই পদ্ধতির ব্যবহার করতে যাচ্ছি। আমি পছন্দ করি যে আমি NSNumber বিভাগের মেটা ডেটা সম্পর্কে আমার সমস্ত অন্যান্য মেটা তথ্যও ধারণ করতে পারি। (অর্থাত্
এনাম মানগুলিতে

সত্যিই দুর্দান্ত ধারণা! স্ট্রিং আইডেন্টিফায়ারদের সংযুক্ত করার জন্য, সরাসরি জেএসএন, কোর ডেটা ইত্যাদিতে ব্যবহার করার জন্য খুব দরকারী
গ্রেগারিয়াস

5

আপনি যদি মজেনেটর ব্যবহার করছেন তবে এটি একবার দেখুন: https://github.com/rentzsch/mogenerator/wiki/Using-enums-as-tyype । আপনার ব্যবহারকারীর তথ্যের মান itemTypeসহ একটি পূর্ণসংখ্যা 16 বৈশিষ্ট্যযুক্ত থাকতে পারে । তারপর, আপনার সত্তা জন্য ব্যবহারকারীকে তথ্য মধ্যে, সেট হেডার যে নাম enum মধ্যে সংজ্ঞায়িত করা হয়। যখন আপনার হেডার ফাইল জেনারেট করার, mogenerator স্বয়ংক্রিয়ভাবে করতে হবে সম্পত্তি আছে প্রকার।attributeValueScalarTypeItemadditionalHeaderFileNameItemItem


2

আমি বৈশিষ্ট্য প্রকারটি 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

1

যেহেতু এনামগুলিকে একটি স্ট্যান্ডার্ড শর্ট দ্বারা সমর্থন করা হয় আপনি এনএসএনবার র‌্যাপারটিও ব্যবহার করতে পারেন না এবং সম্পত্তিটি সরাসরি স্কেলারের মান হিসাবে সেট করতে পারেন না। মূল ডেটা মডেলে ডেটা টাইপটিকে "পূর্ণসংখ্যার 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;

অথবা জেএসএন স্ট্রিং থেকে পার্সিং বা ফাইল থেকে লোড ing

myEntityInstance.coreDataEnumStorage = [myStringOfAnInteger intValue];

1

আমি এটি অনেক কিছু করেছি এবং নিম্নলিখিত ফর্মটি দরকারী বলে খুঁজে পেয়েছি:

// 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"
}

যেহেতু এটি জটিল ডেটা মডেলগুলির জন্য শ্রমসাধ্য হতে পারে, তাই আমি একটি কোড জেনারেটর লিখেছিলাম যা সমস্ত ম্যাপিংগুলি ছুঁড়ে ফেলার জন্য এমওএম / সত্তাগুলি গ্রাস করে। আমার ইনপুটগুলি টেবিল / সারি থেকে এনুম প্রকারের অভিধান হতে পারে। আমি যখন ছিলাম, তখন আমি জেএসওএন সিরিয়ালাইজেশন কোডও উত্পন্ন করেছিলাম। আমি এটি খুব জটিল মডেলের জন্য করেছি এবং এটি একটি বড় সময় রক্ষাকারী হিসাবে দেখা গেছে।


0

নীচে আটকানো কোডটি আমার পক্ষে কাজ করে এবং আমি এটিকে পুরো কাজের উদাহরণ হিসাবে যুক্ত করেছি। আমি এই পদ্ধতির বিষয়ে মতামত শুনতে চাই, যেহেতু আমি আমার অ্যাপ্লিকেশনগুলিতে এটি ব্যাপকভাবে ব্যবহার করার পরিকল্পনা করছি।

  • আমি @ynamic জায়গায় রেখেছি, কারণ এটি সম্পত্তিতে নাম লেখক / সেটার দ্বারা সন্তুষ্ট।

  • আইকেনডাকের উত্তর অনুসারে, আমি ডিফল্ট গেটর / সেটারের নামগুলি ওভাররাইড করি নি।

  • আমি টাইপডেফের বৈধ মানগুলিতে একটি এনএসএসার্টের মাধ্যমে কিছু পরিসীমা চেকিং অন্তর্ভুক্ত করেছি।

  • প্রদত্ত টাইপিডেফের জন্য স্ট্রিংয়ের মান পেতে আমি একটি পদ্ধতিও যুক্ত করেছি।

  • আমি "কে" পরিবর্তে "সি" দিয়ে ধ্রুবক উপস্থাপন করি। আমি "কে" (গণিতের উত্স, historicalতিহাসিক) এর পেছনের যুক্তিটি জানি, তবে মনে হয় এটির সাথে আমি ইএসএল কোডটি পড়ছি, তাই আমি "সি" ব্যবহার করি। শুধু একটি ব্যক্তিগত জিনিস।

এখানে একটি অনুরূপ প্রশ্ন রয়েছে: কোর ডেটা টাইপ হিসাবে টাইপডেফ

আমি এই পদ্ধতির কোনও ইনপুট প্রশংসা করব।

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

0

অটো জেনারেটেড ক্লাসগুলির সলিউশন

এক্সকোডের কোড জেনারেটর থেকে (আইওএস 10 এবং উপরে)

যদি আপনি "আপনার ক্লাস" নামে একটি সত্তা তৈরি করেন তবে এক্সকোড স্বয়ংক্রিয়ভাবে "ডেটা মডেল ইন্সপেক্টর" তে একটি কোডজেন ধরণের ডিফল্ট হিসাবে "শ্রেণি সংজ্ঞা" বেছে নেবে। এটি নীচের ক্লাস তৈরি করবে:

সুইফ্ট সংস্করণ:

// YourClass+CoreDataClass.swift
  @objc(YourClass)
  public class YourClass: NSManagedObject {
  }

উদ্দেশ্য-সি সংস্করণ:

// YourClass+CoreDataClass.h
  @interface YourClass : NSManagedObject
  @end

  #import "YourClass+CoreDataProperties.h"

  // YourClass+CoreDataClass.m
  #import "YourClass+CoreDataClass.h"
  @implementation YourClass
  @end

আমরা এক্সকোডে "শ্রেণি সংজ্ঞা" এর পরিবর্তে কোডজেন বিকল্প থেকে "বিভাগ / এক্সটেনশন" বেছে নেব।

এখন, আমরা যদি কোনও এনাম যুক্ত করতে চাই, তবে যান এবং আপনার অটো-উত্পন্ন শ্রেণীর জন্য অন্য এক্সটেনশন তৈরি করুন এবং নীচের মতো এখানে আপনার এনাম সংজ্ঞা যুক্ত করুন:

// 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;

এছাড়াও পরীক্ষা করে দেখুন

এক্সকোড স্বয়ংক্রিয় সাবক্লাস জেনারেশন

এক্সকোড এখন মডেলিং সরঞ্জামে NSManagedObject সাবক্লাসগুলির স্বয়ংক্রিয় প্রজন্মকে সমর্থন করে। সত্তা পরিদর্শক ইন:

ম্যানুয়াল / কোনওটিই ডিফল্ট এবং পূর্ববর্তী আচরণ নয়; এই ক্ষেত্রে, আপনার নিজের সাবক্লাসটি প্রয়োগ করা উচিত বা এনএসম্যানেজডঅবজেক্ট ব্যবহার করা উচিত। শ্রেণি / এক্সটেনশন ক্লাসনাম + কোরডেটা জেনারেটেডপ্রোপার্টি জাতীয় নামের একটি ফাইলে একটি শ্রেণিবদ্ধকরণ উত্পন্ন করে। আপনাকে প্রধান শ্রেণি ঘোষণা করতে / বাস্তবায়ন করতে হবে (যদি ওবজে-সি-তে থাকে তবে একটি শিরোনামের মাধ্যমে এক্সটেনশনটি ক্লাসনেম। H নামে পরিচিতি আমদানি করতে পারে)। শ্রেণি সংজ্ঞা ক্লাসনাম + কোরিডাটা ক্লাসের মতো নামের সাবক্লাস ফাইলগুলি যেমন বিভাগ / এক্সটেনশনের জন্য উত্পন্ন ফাইল উত্পন্ন করে। উত্পন্ন ফাইলগুলি ডেরিভডটাতে স্থাপন করা হয় এবং মডেলটি সংরক্ষণের পরে প্রথম বিল্ডে পুনরায় তৈরি করা হয়। এগুলি এক্সকোড দ্বারাও সূচিত হয়, সুতরাং রেফারেন্সগুলিতে কমান্ড-ক্লিক করা এবং ফাইল-এর কাজ দ্বারা দ্রুত খোলার কাজ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.