2012-02-28 11 views
6

मैं अपने मॉडल वर्गों के लिए एक सामान्य एन्कोडर और डिकोडर बनाने की कोशिश कर रहा था। मैं "एन्कोड विधि" को सभी प्रकार की संपत्तियों, या तो ऑब्जेक्ट्स (एनएसएसटींग, एनएसएनंबर, एनएसएआरएआरई, आदि ...) और आदिम प्रकारों के लिए कॉल करने का तरीका खोजने का प्रयास कर रहा था। और मैंने देखा कि कोई निम्नलिखित कर रहा है। और मैं सोच रहा था कि क्या यह करने का सही तरीका होगा।एनएससीओडी: प्राचीन प्रकार के लिए एन्कोडर और डिकोडर

गुण:

@property (assign,nonatomic) int integerP; 
@property (assign,nonatomic) float floatP; 
@property (assign,nonatomic) BOOL boolP; 

Enconder और डिकोडर कोड:

- (void)encodeWithCoder:(NSCoder *)encoder 
{ 
    id object2 = [self valueForKey:@"integerP"]; 
    id object3 = [self valueForKey:@"floatP"]; 
    id object4 = [self valueForKey:@"boolP"]; 


    [encoder encodeObject:object2 forKey:@"integerP"]; 
    [encoder encodeObject:object3 forKey:@"floatP"]; 
    [encoder encodeObject:object4 forKey:@"boolP"]; 

    //[self setValue:[NSNumber numberWithInt:90] forKey:@"heightR"]; 

    //NSLog(@"%@",[self valueForKey:@"heightR"]); 


} 

- (id)initWithCoder:(NSCoder *)decoder 
{ 
    self = [super init]; 
    if(self != nil) 
    { 

     id object2 = [decoder decodeObjectForKey:@"integerP"]; 
     [self setValue:object2 forKey:@"integerP"]; 
     id object3 = [decoder decodeObjectForKey:@"floatP"]; 
     [self setValue:object3 forKey:@"floatP"]; 
     id object4 = [decoder decodeObjectForKey:@"boolP"]; 
     [self setValue:object4 forKey:@"boolP"]; 

    } 
    return self; 
} 

मैं अगर यह एक सही तरीका है, या यकीन नहीं था अन्य प्रोग्राम या वस्तु में लिख सकता है अगर आदिम गुणों की एक ही स्मृति स्थान।

तरह से मैंने सोचा था कि सही था:

- (void)encodeWithCoder:(NSCoder *)encoder 
{ 


    [encoder encodeInt:integerP forKey:@"integerP"]; 
    [encoder encodeFloat:floatP forKey:@"floatP"]; 
    [encoder encodeBool:boolP forKey:@"boolP"]; 

    //[self setValue:[NSNumber numberWithInt:90] forKey:@"heightR"]; 

    //NSLog(@"%@",[self valueForKey:@"heightR"]); 


} 

- (id)initWithCoder:(NSCoder *)decoder 
{ 
    self = [super init]; 
    if(self != nil) 
    { 
     integerP = [decoder decodeIntForKey:@"integerP"]; 
     floatP = [decoder decodeFloatForKey:@"floatP"]; 
     boolP = [decoder decodeBoolForKey:@"boolP"]; 


    } 
    return self; 
} 

मैं परीक्षण किया है और दोनों तरीकों सही मान लौटे तो विधि ऊपर सही है, ऊपर है और इस के बीच अंतर क्या है।

+0

मुझे समझ नहीं आता। एन्कोडिंग/डिकोडिंग आदिम प्रकारों के लिए पहले से ही विधियां हैं, आप उनका उपयोग क्यों नहीं करेंगे? मेरे लिए, दूसरी विधि अधिक सही है। – Bejil

उत्तर

8

दोनों विधियां काम करेंगे।

पहले, विशेष रूप से चतुर है जा रहा है कि valueForKey: हमेशा एक NSObject वापस आ जाएगी, तब भी जब मूल्य वास्तव में एक आदिम है, इसलिए नाव/पूर्णांक/bool प्रकार एक NSNumber में KVC गेटर द्वारा स्वचालित रूप से लिपटे हो जाएगा, और में unwrapped केवीसी सेटर।

कुछ प्रकार के सामान्य एनकोड/डीकोड फ़ंक्शंस को लागू करने के लिए इसका उपयोग करना संभव हो सकता है जो कि संपत्ति कुंजी की सरणी पर काम करता है।

हालांकि, दूसरा उदाहरण यह करने का मानक तरीका है, और जिस तरह से मैं शायद अनुशंसा करता हूं। कभी-कभी आपको बॉयलरप्लेट कोड लिखना पड़ता है! फिर उस आधार वर्ग से वास्तविक डेटा के साथ अपने वर्ग निकाले जाते हैं

BaseModel.h

@interface BaseModel : NSObject<NSCoding> 
@end 

BaseModel.m

- (NSArray *)keysForEncoding 
{ 
    [NSException raise:@"keysForEncoding" format:@"keysForEncoding must be implemented in child class!"]; 
    //example implementation in child class: 
    //return @[@"airtime", @"channelID", @"duration", @"programID", @"shortTitle"]; 
    return nil; 
} 


-(void)encodeWithCoder:(NSCoder *)aCoder 
{ 
    for(NSString* key in [self keysForEncoding]) 
    { 
     [aCoder encodeObject:[self valueForKey:key] forKey:key]; 
    } 
} 

-(id)initWithCoder:(NSCoder *)aDecoder 
{ 
    self = [super init]; 
    if (self) { 
     for (NSString* key in [self keysForEncoding]) { 
      [self setValue:[aDecoder decodeObjectForKey:key] forKey:key]; 
     } 
    } 
    return self; 
} 

:

+0

यह जानना अच्छा है कि दोनों काम करेंगे और इसका उपयोग करना ठीक है। लेकिन, आप दूसरे की सिफारिश क्यों करेंगे? यदि आप दूसरी विधि का उपयोग करते हैं तो क्या आपको किसी प्रकार का प्रदर्शन लाभ पता है? - अभी के लिए, मेरे पास जेनेरिक एन्कॉन्डे/डीकोड लिखने के लिए 2 विकल्प हैं, या तो ऊपर पोस्ट की गई पहली एन्कोड विधि का उपयोग करें या एनएस डिक्शनरी का उपयोग करें जिसमें मेरे सभी आदिम गुण होंगे। आप किस तरह से सिफारिश करेंगे? – lao

+0

मुझे निश्चित रूप से पता नहीं है, लेकिन मेरा मानना ​​है कि नगण्य प्रदर्शन अंतर होगा। यदि आप NSDictionary में प्राइमेटिव संग्रहीत कर रहे थे, तो आपको ऐसा करने से पहले उन्हें NSNumbers में परिवर्तित करना होगा, इसलिए यह प्रभावी रूप से एक ही चीज़ है। मेरी सिफारिश केवल मैन्युअल रूप से एन्कोड/डीकोड लिखना होगा, लेकिन यदि आप जेनेरिक एन्कोड/डीकोड का प्रयास करना चाहते हैं, तो पहला सबसे अच्छा विकल्प होगा। हालांकि, यदि प्रदर्शन एक बड़ा मुद्दा है, तो आपको वास्तव में कोर डेटा मॉडल पर जाने पर विचार करना चाहिए। बड़े ऑब्जेक्ट पेड़ एन्कोडिंग पर एनएससीओडर बहुत धीमी है। – joerick

+0

हाँ, मुझे कल्पना है कि यह भी एक छोटा प्रदर्शन अंतर हो सकता है। अभी के लिए, मुझे लगता है कि मैं पहली विधि का उपयोग कर जेनेरिक एन्कोडर/डिकोडर लिखूंगा। मुझे विश्वास नहीं है कि इससे मुझे कोई बड़ा प्रदर्शन अंतर आएगा और मुझे अन्य परियोजनाओं के लिए बहुत समय बचाएगा। और हाँ, मैं बड़ी वस्तुओं के लिए कोर डेटा मॉडल का उपयोग करूंगा, मैं केवल छोटे prefs ऑब्जेक्ट्स के लिए एनएससीओडर का उपयोग करने की योजना बना रहा हूं। लेकिन धन्यवाद! – lao

1

आप पहली विधि बहुत अजीब लगती है!

उद्देश्य-सी float/int/BOOL "ऑब्जेक्ट" नहीं हैं। आप को फोन करके एक NSNumber में उन्हें परिवर्तित कर सकते हैं:

लेकिन अपने दूसरे समाधान ठीक लग रहा है।
केवल या NSArray, आदि जैसे वस्तुओं अपने स्वयं के वर्ग के लिए decodeObjectForKey उपयोग करें (इसमें आप भी कोडिंग/डिकोडिंग तरीकों जोड़ने की जरूरत है!)

और setValue और valueForKey से अपनी उंगलियों को छोड़ दें।

1

इस प्रयास करें।

साधारण क्लास का उदाहरण:

EPGData.h

@interface EPGData : BaseModel 
    @property(nonatomic, assign) NSTimeInterval airtime; //date in 1970 format 
    @property(nonatomic, assign) int channelID; 
    @property(nonatomic, assign) float duration; //in seconds 
    @property(nonatomic, assign) unsigned int programID; 
    @property(nonatomic, strong) NSString* shortTitle; 
    @end 

EPGData.m

- (NSArray *)keysForEncoding; 
{ 
    return [NSArray arrayWithObjects:@"airtime", @"channelID", @"duration", @"programID", @"shortTitle", nil]; 
} 
संबंधित मुद्दे