开发者

Problem with NSMutableArray & object retrieval from it, populated from NSXMLParser

I'm a newbie to Objective-C & iPhone development, hence please bear with me.

I'm working on an app which loads with UITableView and upon selecting one particular cell called "Address Book" it should load with another UITableView containing all the addresses retrieved from a web request. Using NSXMLParser's delegate methods I'm storing those addresses into a NSMutableArray defined in the loaded view's header file. But the problem occurs when those addresses are being displayed onto the UITableView cells (yes, I have got the count for the number of cells). Can anybody please help me with this problem? I'm stuck on this for days now !!! Following is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}

AddressEntry *entry = (AddressEntry *)[self.addresses objectAtIndex:indexPath.row];

@try
{
    NSLog(@"%@", entry.firstName);
}
@catch (NSException * e) 
{
    @try 
    {
        NSLog(@"%@", entry.lastName);
    }
    @catch (NSException * e) 
    {
        NSLog(@"%@", entry.lastName);
    }
}
[entry release];

return cell;
}

    - (void)parserDidStartDocument:(NSXMLParser *)parser
{
    self.currentElement = nil;
    self.f_Name = nil;
    self.l_Name = nil;
    self.phone = nil;
    self.email = nil;
    count = 0;
    self.addresses = [[NSMutableArray alloc] init];
}

- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
                   开发者_运维问答                  namespaceURI:(NSString *)namespaceURI 
                                    qualifiedName:(NSString *)qName 
                                       attributes:(NSDictionary *)attributeDict
{


if([elementName isEqualToString:@"Entries"])
    {
        count = [[attributeDict valueForKey:@"total"] intValue];
    }
    else if([elementName isEqualToString:@"FirstName"])
    {       
        [self.f_Name release];
        self.f_Name = [[NSString alloc] init];
    }
    else if([elementName isEqualToString:@"LastName"])
    {
        [self.l_Name release];
        self.l_Name = [[NSString alloc] init];
    }
    else if([elementName isEqualToString:@"PhoneNumber"])
    {
        [self.phone release];
        self.phone = [[NSString alloc] init];
    }
    else if([elementName isEqualToString:@"EmailAddress"])
    {
        [self.email release];
        self.email = [[NSString alloc] init];
    }
    else if([elementName isEqualToString:@"Record"])
    {
        [self.addrEntry release];
        self.addrEntry = [[[AddressEntry alloc] init] retain];
    }

[self.currentElement release];
self.currentElement = nil;
self.currentElement = [elementName copy];
}


- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
                                       namespaceURI:(NSString *)namespaceURI 
                                      qualifiedName:(NSString *)qName
{
    //
    if([elementName isEqualToString:@"FirstName"])
        self.addrEntry.firstName = self.f_Name;
    else if ([elementName isEqualToString:@"LastName"])
        self.addrEntry.lastName = self.l_Name;
    else if([elementName isEqualToString:@"PhoneNumber"])
        self.addrEntry.mobile = self.phone;
    else if([elementName isEqualToString:@"EmailAddress"])
        self.addrEntry.emailAddress = self.email;
    else if([elementName isEqualToString:@"Record"])
    {
        [self.addresses addObject:self.addrEntry];
        [self.addrEntry release];
        self.addrEntry = nil;
        /*AddressEntry *e = (AddressEntry *)[self.addresses lastObject];
        NSLog(@"%@ %@ %@ %@", e.firstName, e.lastName, e.mobile, e.emailAddress);
        [e release];*/
    }
}


- (void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if([currentElement isEqualToString:@"FirstName"])
        self.f_Name = string;
    else if([currentElement isEqualToString:@"LastName"])
        self.l_Name = string;
    else if([currentElement isEqualToString:@"PhoneNumber"])
        self.phone = string;
    else if([currentElement isEqualToString:@"EmailAddress"]) 
    {
        self.email = string;
    }

}


The most likely reason for the app crashing is this line in cellForRowAtIndexPath:

[entry release];

You did not alloc/init the variable entry there so don't call release on it. Remove that line.

In that method, entry is only holding a reference to an already-allocated object in the address array. It doesn't "own" the object so it shouldn't release it.

This page in the Apple docs shows a nice flow diagram and some simple rules for memory management that might help in understanding this better.


As a separate issue unrelated to the crashing, the use of @try/@catch in your example seems unnecessary. See this answer for an explanation.


Finally, also unrelated to the crashing, in foundCharacters, you should really be appending the string parameter to your data instead of just assigning because it's possible for that method to be called multiple times within the same value. See Handling XML Elements and Attributes for an example.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜