2012-02-14 71 views
0

,我發現了以下錯誤:objectForKey誤差的NSXMLParser

「這一類不是鍵值編碼兼容的關鍵temp_f」

我AppDelegate類文件:

#import <Cocoa/Cocoa.h> 

@interface AppDelegate : NSObject <NSApplicationDelegate> { 
    IBOutlet NSTableView *tableView; 
    NSArray *current; 
} 

@property (assign) IBOutlet NSWindow *window; 
@end 

#import "AppDelegate.h" 
#import "CurrentWeather.h" 
#import "XMLCurrent.h" 

@implementation AppDelegate 

@synthesize window = _window; 

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { 
    XMLCurrent *currentXML = [[XMLCurrent alloc] init]; 
    NSError *error = nil; 

    current = [currentXML fetchCurrentWithError:&error]; 
    [tableView reloadData]; 
} 

- (NSInteger)numberOfRowsInTableView:(NSTableView *)theTableView { 
    return [current count]; 
} 

- (id)tableView:(NSTableView *)theTableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 
    CurrentWeather *c = [current objectAtIndex:row]; 
    return [c valueForKey:[tableColumn identifier]]; 
} 
@end 

我的CurrentWeather類文件:

#import <Foundation/Foundation.h> 

@interface CurrentWeather : NSObject { 
    NSString *location; 
    NSString *weather; 
    NSString *degreesF; 
} 

@property (nonatomic, copy) NSString *location; 
@property (nonatomic, copy) NSString *weather; 
@property (nonatomic, copy) NSString *degreesF; 

@end 

#import "CurrentWeather.h" 

@implementation CurrentWeather 

@synthesize location, weather, degreesF; 

@end 

我的XMLCurrent類文件:

#import <Foundation/Foundation.h> 

@interface XMLCurrent : NSObject <NSXMLParserDelegate> { 
    NSMutableArray *current; 
    NSMutableString *currentString; 
    NSMutableDictionary *currentFields; 
} 

- (NSArray *)fetchCurrentWithError:(NSError **)outError; 

@end 

#import "XMLCurrent.h" 
#import "CurrentWeather.h" 

@implementation XMLCurrent 

- (id)init { 
    self = [super init]; 

    if (self) { 
     current = [[NSMutableArray alloc] init]; 
    } 
    return self; 
} 

- (NSArray *)fetchCurrentWithError:(NSError **)outError { 
    BOOL success; 

    NSURL *xmlURL = [NSURL URLWithString:@"http://www.weather.gov/xml/current_obs/KCLT.xml"]; 

    NSURLRequest *req = [NSURLRequest requestWithURL:xmlURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30]; 

    NSURLResponse *resp = nil; 

    NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&resp error:outError]; 
    if (!data) { 
     return nil; 
    } 

    [current removeAllObjects]; 

    NSXMLParser *parser; 
    parser = [[NSXMLParser alloc] initWithData:data]; 
    [parser setDelegate:self]; 

    success = [parser parse]; 
    if (!success) { 
     *outError = [parser parserError]; 
     return nil; 
    } 

    NSArray *output = [current copy]; 
    return output; 
} 

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName 
    attributes:(NSDictionary *)attributeDict { 

    if ([elementName isEqual:@"current_observation"]) { 
     currentFields = [[NSMutableDictionary alloc] init]; 
    } 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
    namespaceURI:(NSString *)namespaceURI 
qualifiedName:(NSString *)qName { 

    if ([elementName isEqual:@"current_observation"]) { 
     CurrentWeather *currentCond = [[CurrentWeather alloc] init]; 
     [currentCond setLocation:[currentFields objectForKey:@"location"]]; 
     [currentCond setWeather:[currentFields objectForKey:@"weather"]]; 
     [currentCond setDegreesF:[currentFields objectForKey:@"temp_f"]]; 

     [current addObject:currentCond]; 
     currentCond = nil; 
     currentFields = nil; 
    } else if (currentFields && currentString) { 
     NSString *trimmed; 
     trimmed = [currentString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     [currentFields setObject:trimmed forKey:elementName]; 
    } 
    currentString = nil; 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if (!currentString) { 
     currentString = [[NSMutableString alloc] init]; 
    } 
    [currentString appendString:string]; 
} 
@end 

這些鍵用作表格視圖中的「標識符」。出於某種原因,如果密鑰中有下劃線(例如temp_f),則會出現錯誤。下劃線是必要的,因爲它是XML文件中元素的名稱。如果沒有下劃線,則沒有錯誤。我如何從包含下劃線的XML元素獲取數據?

xml數據正在從http://www.weather.gov/xml/current_obs/KCLT.xml

+0

什麼_is_'currentFields'?它在哪裏創建? – 2012-02-14 21:25:48

+0

請將代碼放在currentFields設置的位置。 – 2012-02-14 21:26:11

+1

好的,現在你在哪裏添加對象到currentFields? – 2012-02-14 21:35:35

回答

3

CurrentWeather解析有degreesF屬性,你從temp_f XML字段設置。您需要將表列的標識符設置爲「degreesF」而不是「temp_f」。這與temp_f無關,包含下劃線。相反,問題在於CurrentWeather並非鍵值「temp_f」的鍵值編碼(就像錯誤狀態),因爲它沒有名爲「temp_f」的屬性。

更詳細地解釋,在您的-tableView:objectValueForTableColumn:方法中,您將列的標識符用作CurrentWeather實例的鍵。由於標識符是「temp_f」,因此您可以這樣做:[c valueForKey:@"temp_f"]。這會引發異常,因爲CurrentWeather沒有temp_f屬性。

+0

Aaaahhhh!謝謝,那就做到了! – wigging 2012-02-14 22:39:45