代码之家  ›  专栏  ›  技术社区  ›  Johan Wikström

在对象内使用as NSString进行NSCoding

  •  7
  • Johan Wikström  · 技术社区  · 14 年前

    Store 对象,我的所有NSString属性 BadAccess 错误。int和double属性工作正常!

    存储.h

    @interface Store : NSObject<NSCoding> {
        NSString *Name;
        NSString *Address;
        NSString *Phone;
        double GeoLong;
        double GeoLat;
        int ID;         
    }
    
    @property (nonatomic, retain) NSString *Name;
    @property (nonatomic, retain) NSString *Address;
    @property (nonatomic, retain) NSString *Phone;
    @property (nonatomic) double GeoLat;
    @property (nonatomic) double GeoLong;
    @property (nonatomic) int ID;
    
    @end
    

    存储.m

    @implementation Store
    
    @synthesize Name;
    @synthesize ID;
    @synthesize Address;
    @synthesize Phone;
    @synthesize GeoLat;
    @synthesize GeoLong;
    
    
    /** Implentation of the NSCoding protocol. */
    
    -(void)encodeWithCoder:(NSCoder *)encoder
    {
        [encoder encodeInt:ID forKey:@"ID"];
        [encoder encodeDouble:GeoLat forKey:@"GeoLat"];
        [encoder encodeDouble:GeoLong forKey:@"GeoLong"];
        NSLog(@"Name in encode: %@", Name); //WORKS!
        [encoder encodeObject:Name forKey:@"Name"];
        [encoder encodeObject:Phone forKey:@"Phone"];
        [encoder encodeObject:Address forKey:@"Address"];
    
    }
    
    -(id)initWithCoder:(NSCoder *)decoder
    {
        // Init first.
        if(self = [self init]){
    
        ID = [decoder decodeIntForKey:@"ID"];
        GeoLat = [decoder decodeDoubleForKey:@"GeoLat"];
        GeoLong = [decoder decodeDoubleForKey:@"GeoLong"];
        Name = [decoder decodeObjectForKey:@"Name"];
        NSLog(@"Name in decode: %@", Name); //WORKS! logs the name
    
        Address = [decoder decodeObjectForKey:@"Address"];
        Phone = [decoder decodeObjectForKey:@"Phone"];
        }
    
        return self;
    }
    
    - (void)dealloc
    {
        [Name release];
        [ID release];
        [Address release];
        [Phone release];
    
    
        [super dealloc];
    }
    @end
    

    //streams contains the data i will populate my array with. 
    for (ndx = 0; ndx < streams.count; ndx++) {
                NSDictionary *stream = (NSDictionary *)[streams objectAtIndex:ndx];
    
                Store *item = [[Store alloc] init] ;
                item.Name = [stream valueForKey:@"Name"];
                item.Address = [stream valueForKey:@"Address"];
                item.Phone = [stream valueForKey:@"Phone"];
                item.GeoLat = [[stream valueForKey:@"GeoLat"] doubleValue];
                item.GeoLong = [[stream valueForKey:@"GeoLong"] doubleValue];                
                item.ID = [[stream valueForKey:@"ID"] intValue]; 
    
                [listToReturn addObject:item];
            }
        }
    
        //test to check if it works
        for(int i = 0; i < [listToReturn count]; i++){
            Store *item = (Store *)[listToReturn objectAtIndex:i];
            NSLog(@"Name: %@", item.Name); //works
        }
    
        //save
        [[NSUserDefaults standardUserDefaults] setObject:[NSKeyedArchiver archivedDataWithRootObject:listToReturn] forKey:@"stores"];
    
        // retrieve
        NSMutableArray *stores = [NSMutableArray new];
        NSUserDefaults *currentDefaults = [NSUserDefaults standardUserDefaults];
        NSData *dataRepresentingSavedArray = [currentDefaults objectForKey:@"stores"];
        if (dataRepresentingSavedArray != nil)
        {
            NSArray *oldSavedArray = [NSKeyedUnarchiver unarchiveObjectWithData:dataRepresentingSavedArray];
            if (oldSavedArray != nil)
                stores = [[NSMutableArray alloc] initWithArray:oldSavedArray];
            else
                stores = [[NSMutableArray alloc] init];
        }
    
        if ([stores count] > 0) {
            NSMutableArray * annotations =  [[NSMutableArray alloc] init];
            for(int i = 0;i< [stores count]; i++){
    
                Store *store = [stores objectAtIndex: i];
    
                CLLocationCoordinate2D location;
                if(store.GeoLat != 0 && store.GeoLong != 0){
                    location.latitude = store.GeoLat;
                    location.longitude = store.GeoLong; //works 
                    NSLog(@"Adding store: %@", store.Name); //DONT WORK!! <-- MAIN PROBLEM
                }
            }
        }
    

    感觉好像我什么都试过了,但却搞不清楚它在解码时是如何工作的,但当我把它放入一个数组后,却不知道它在循环数组时是如何工作的。

    有人有什么想法吗?

    1 回复  |  直到 7 年前
        1
  •  13
  •   nschum Solin    14 年前

    你没有保留酒店的财产 initWithCoder .

    Name = [decoder decodeObjectForKey:@"Name"];
    

    以下是在案例中保留属性的两种方法:

    self.Name = [decoder decodeObjectForKey:@"Name"];
    Name = [[decoder decodeObjectForKey:@"Name"] retain];