سؤال

I've made an XMLParser class in objective-c and I can't seem to set the iVars in my shared store within the parser process, I've tried numerous ways but I'm getting nowhere.

This is my code and what is being returned, Here's hoping it's a small syntax error I've overlooked.

.h

@interface XMLParser : NSXMLParser <NSXMLParserDelegate>
{
    XMLParser *XMLStore;
}

@property(nonatomic, weak)NSMutableString *longitudeValue;
@property(nonatomic, weak)NSMutableString *latitudeValue;

+ (XMLParser *)sharedStore;
- (void)parseXMLAtURL:(NSURL *)url;

@end

.m

#import "XMLParser.h"

@implementation XMLParser

BOOL blockLatLong = NO;
NSMutableString *currentNodeContent;

+ (XMLParser *)sharedStore
{
    static XMLParser *XMLStore = nil;
    if (!XMLStore)
        XMLStore = [[XMLParser alloc] init];

    return XMLStore;
}

- (void)parseXMLAtURL:(NSURL *)url
{
    NSXMLParser *parser = [[XMLParser alloc] initWithContentsOfURL:url];

    parser.delegate = self;

    [parser setShouldProcessNamespaces:NO];
    [parser setShouldReportNamespacePrefixes:NO];
    [parser setShouldResolveExternalEntities:NO];

    [parser parse];
    NSLog(@"Long:%@, Lat:%@", XMLStore.longitudeValue, XMLStore.latitudeValue);
}

-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    currentNodeContent = [NSMutableString stringWithString:string];
}




-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"geometry"]){
        blockLatLong = YES;
    }

    if ([elementName isEqualToString:@"location_type"]){
        blockLatLong = NO;
    }
}




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

    if ([elementName isEqualToString:@"lng"]){
        [XMLStore setLongitudeValue:currentNodeContent];
        NSLog(@"%@", currentNodeContent);
        NSLog(@"%@", XMLStore.longitudeValue);
    }

    if ([elementName isEqualToString:@"lat"]){
        [XMLStore setLatitudeValue:currentNodeContent];
        NSLog(@"%@", currentNodeContent);
        NSLog(@"%@", XMLStore.latitudeValue);
    }

    }
}


@end

Log

2013-09-23 11:19:59.606 Weathalert[640:c07] 40.7143528
2013-09-23 11:19:59.606 Weathalert[640:c07] (null)
2013-09-23 11:19:59.607 Weathalert[640:c07] -74.0059731
2013-09-23 11:19:59.607 Weathalert[640:c07] (null)
2013-09-23 11:19:59.607 Weathalert[640:c07] Long:(null), Lat:(null)
هل كانت مفيدة؟

المحلول

Your problem is that you've got three instances of XMLParser where you could be setting the instance variable:

  1. Local NSXMLParser *parser allocated inside parseXMLAtURL:,
  2. Function-static static XMLParser *XMLStore allocated inside sharedStore, and
  3. Instance variable XMLParser *XMLStore; which you never allocate, so it stays nil.

It is the third instance on which you try calling your setters. Since it's nil, the calls have no effect: [XMLStore setLongitudeValue:...] does nothing.

To fix this, drop the second and the third variables, along with the +(XMLParser *)sharedStore method. Use the regular instance properties, rather than accessing the shared one.

You can harvest the results from the local parser variable upon completion of the [parser parse] call:

NSLog(@"Long:%@, Lat:%@", parser.longitudeValue, parser.latitudeValue);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top