j. Doe j. Doe - 2 months ago 13
iOS Question

Getting nil from property

I have 2 classes,

NSObject
class
DataParser
and a
ViewController
. In
DataParser
class I have some methods that parses XML and results are saved into an array which is a property of
DataParser
class. I want to show results to user in my
ViewController
. I have here this property
@property (strong, nonatomic) DataParser *parser;
and in
viewWillAppear
method I created instance of
DataParser
class and I'm trying to get array with results this way

self.parser = [[DataParser alloc] init];
[self.parser downloadBooksXML];
NSLog(@"%@", self.parser.array);


but I'm still getting nil. Does anyone know where could be the problem?

- (void)downloadBooksXML
{
NSURL *url = [NSURL URLWithString:@"http://..."];

[self downloadDataFromURL:url withCompletionHandler:^(NSData *data) {
if (data) {
self.xmlParser = [[NSXMLParser alloc] initWithData:data];
self.xmlParser.delegate = self;
self.foundValue = [[NSMutableString alloc] init];
[self.xmlParser parse];
} else {
NSLog(@"Error");
}
}];
}


EDIT: When I nslog array in
DataParser
class in
parserDidEndDocument
method, it contains data

Answer

When [self.parser downloadBooksXML] returns, self.parser.array has not been set yet, because the data has not been downloaded and parsed.

The data will be available once the document is done parsing, which you can check using the delegate method:

- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"%@", self.parser.array);
}

You can therefore use a pattern like this:

- (void) viewDidLoad {
    [super viewDidLoad];
    self.parser = [[DataParser alloc] init];
    [self.parser downloadBooksXML];
}

- (void) dataFinished {
    NSLog(@"%@", self.parser.array);
    // update the user interface
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
   [self dataFinished];
}

Depending on the implementation of your other code, you might need to switch to the main queue to update the UI:

- (void) dataFinished {
    NSLog(@"%@", self.parser.array);

    dispatch_async(dispatch_get_main_queue(), ^(void){
        // update the user interface
    });
}
Comments