2012-09-05 22 views
6

मुझे समझ में नहीं आता कि मैं CGPoint structs संग्रह क्यों कर सकता हूं लेकिन CLLocationCoordinate2D structs नहीं। संग्रहकर्ता के लिए क्या अंतर है?NSKeyedArchiver CLLocationCoordinate2D structs के साथ विफल रहता है। क्यूं कर?

प्लेटफार्म आईओएस है। मैं सिम्युलेटर में दौड़ रहा हूं और डिवाइस पर कोशिश नहीं की है।

// why does this work: 
NSMutableArray *points = [[[NSMutableArray alloc] init] autorelease]; 
CGPoint p = CGPointMake(10, 11); 
[points addObject:[NSValue valueWithBytes: &p objCType: @encode(CGPoint)]]; 
[NSKeyedArchiver archiveRootObject:points toFile: @"/Volumes/Macintosh HD 2/points.bin" ]; 

// and this doesnt work: 
NSMutableArray *coords = [[[NSMutableArray alloc] init] autorelease]; 
CLLocationCoordinate2D c = CLLocationCoordinate2DMake(121, 41); 
[coords addObject:[NSValue valueWithBytes: &c objCType: @encode(CLLocationCoordinate2D)]]; 
[NSKeyedArchiver archiveRootObject:coords toFile: @"/Volumes/Macintosh HD 2/coords.bin" ]; 

मैं 2 archiveRootObject पर एक दुर्घटना हो और इस संदेश को कंसोल में छपा है:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSKeyedArchiver encodeValueOfObjCType:at:]: this archiver cannot encode structs' 

उत्तर

18

ठीक है, टॉम, क्या आप कुछ गीक-नेस के लिए तैयार हैं? मैं युवा whippersnappers की इस दुनिया में एक "पुराना" लड़का हूँ। हालांकि, मुझे सी के बारे में कुछ चीजें याद हैं, और मैं सिर्फ दिल में एक गीक हूँ।

typedef struct { double d1, d2; } Foo1; 

और इस:

typedef struct Foo2 { double d1, d2; } Foo2; 

पहले एक गुमनाम संरचना करने के लिए एक प्रकार का अन्य नाम है

वैसे भी, इस बीच एक सूक्ष्म अंतर है। दूसरा struct Foo2 पर एक प्रकार का उपनाम है।

अब, @encode के लिए दस्तावेज़ का कहना है कि निम्नलिखित:

typedef struct example { 
    id anObject; 
    char *aString; 
    int anInt; 
} Example; 

दोनों @encode(example) या @encode(Example) के लिए {[email protected]*i} का परिणाम देगा। तो, इसका तात्पर्य है कि @encode वास्तविक संरचना टैग का उपयोग कर रहा है। एक typedef कि एक गुमनाम struct करने के लिए एक उपनाम बनाता है के मामले में, यह लग रहा है @encode हमेशा बाहर रिटर्न की तरह ? '

इस जांच:

NSLog(@"Foo1: %s", @encode(Foo1)); 
NSLog(@"Foo2: %s", @encode(Foo2)); 

वैसे भी, आप अनुमान लगा सकते हैं कि कैसे CLLocationCoordinate2D परिभाषित किया गया है? हां। आपने यह अनुमान लगाया।

typedef struct { 
CLLocationDegrees latitude; 
CLLocationDegrees longitude; 
} CLLocationCoordinate2D; 

मुझे लगता है कि आपको इस पर एक बग रिपोर्ट दर्ज करनी चाहिए। या तो @encode टूटा हुआ है क्योंकि यह अज्ञात structs पर उपनाम टाइपपीफ का उपयोग नहीं करता है, या CLLocationCoordinate2D को पूरी तरह से टाइप करने की आवश्यकता है, इसलिए यह अज्ञात संरचना नहीं है।

+0

धन्यवाद; यह सही स्पष्टीकरण है! मैं इसे अपने रडार रिपोर्ट में संदर्भित करूंगा :) – TomSwift

0

यह क्योंकि @encode CLLocationCoordinate2D

पर chokes

NSLog(@"coords %@; type: %s", coords, @encode(CLLocationCoordinate2D)); पैदावार coords ( "<00000000 00405e40 00000000 00804440>" ); type: {?=dd}

+1

ठीक है, कि दिलचस्प है। तो @encode हो जाता है कि यह दो युगल के साथ एक संरचना है लेकिन टाइप नाम याद आती है। कैसे? और वास्तव में, टाइपनाम एक एन्कोडेड संरचना के लिए क्यों मायने रखता है? – TomSwift

+0

मुझे लगता है कि एन्कोड एक स्ट्रिंग उत्पन्न करता है जिसका उपयोग '[[एनएससीएलएएसएफआरस्ट्रिंग (@encode (name)) alloc] init]' या कुछ समान काले जादू 'है जो' CLLocationCoord' या 'NSPoint' या whatnot उत्पन्न करता है । – Clay

3

इस सीमा के आस-प्राप्त करने के लिए जब तक बग तय हो गई है, बस निर्देशांक नीचे तोड़ने के लिए और फिर से संगठित:

- (void)encodeWithCoder:(NSCoder *)coder 
{ 
    NSNumber *latitude = [NSNumber numberWithDouble:self.coordinate.latitude]; 
    NSNumber *longitude = [NSNumber numberWithDouble:self.coordinate.longitude]; 
    [coder encodeObject:latitude forKey:@"latitude"]; 
    [coder encodeObject:longitude forKey:@"longitude"]; 
    ... 

- (id)initWithCoder:(NSCoder *)decoder 
{ 
    CLLocationDegrees latitude = (CLLocationDegrees)[(NSNumber*)[decoder decodeObjectForKey:@"latitude"] doubleValue]; 
    CLLocationDegrees longitude = (CLLocationDegrees)[(NSNumber*)[decoder decodeObjectForKey:@"longitude"] doubleValue]; 
    CLLocationCoordinate2D coordinate = (CLLocationCoordinate2D) { latitude, longitude }; 
    ... 
संबंधित मुद्दे