2011-01-17 5 views
0

Ich bin ein Neuling zu Objective-C & iPhone Entwicklung, daher bitte ertragen mit mir.Problem mit NSMutableArray und Objektabruf von ihm, bevölkert von NSXMLParser

Ich arbeite an einer App, die mit UITableView lädt und nach der Auswahl einer bestimmten Zelle namens "Adressbuch" sollte es mit einem anderen UITableView laden, die alle Adressen aus einer Webanfrage enthalten. Mit den Delegate-Methoden von NSXMLParser speichere ich diese Adressen in einem NSMutableArray, das in der Headerdatei der geladenen Ansicht definiert ist. Aber das Problem tritt auf, wenn diese Adressen auf den UITableView-Zellen angezeigt werden (ja, ich habe die Anzahl für die Anzahl der Zellen erhalten). Kann mir bitte jemand bei diesem Problem helfen? Ich stecke seit Tagen fest !!! Im Anschluss ist mein 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; 
    } 

} 
+0

Was ist Ihr tatsächliches Problem? – MusiGenesis

+0

Entschuldigung dafür, nicht klar zu sein. Die App stürzt nur ab, nachdem sie diese Zeile getroffen hat @try { NSLog (@ "% @", entry.firstName); } –

+0

Jeder bitte helfen, es bringt mich um (in meinem Kopf) !!! –

Antwort

0

Der wahrscheinlichste Grund für die App abstürzt ist diese Linie in cellForRowAtIndexPath:

[entry release]; 

Sie haben es nicht alloc/init die Variable entry so nicht nennen release auf es. Entferne diese Zeile.

Bei dieser Methode enthält entry nur einen Verweis auf ein bereits zugewiesenes Objekt im Adressfeld. Es besitzt das Objekt nicht, also sollte es es nicht freigeben.

This page in the Apple docs zeigt ein schönes Flussdiagramm und einige einfache Regeln für die Speicherverwaltung, die dabei helfen könnten, dies besser zu verstehen.


Als eine separate Frage, die nichts mit dem Absturz zu tun hat, scheint die Verwendung von @try/@catch in Ihrem Beispiel unnötig. Eine Erläuterung finden Sie unter this answer.


schließlich auch in keinem Zusammenhang mit dem Krachen, in foundCharacters, sollen Sie wirklich die string Parameter auf Ihre Daten angehängt werden zuweisen, anstatt nur, weil es für diese Methode möglich ist, mehrmals im gleichen Wert aufgerufen werden. Ein Beispiel finden Sie in Handling XML Elements and Attributes.

+0

Vielen Dank, aBitObvious für Ihre Antwort! Das habe ich letzten Abend geändert, und jetzt stürzt die App zumindest nicht ab. Aber das brachte mich dazu, in ein anderes bösartiges Problem zu geraten :-('self.addresses', was ein' NSMutableArray' ist, das in den Delegate-Methoden 'NSXMLParser' aufgefüllt ist. Wenn ich versuche, auf die Elemente derselben in der' cellForRowAtIndexPath'-Methode von UITableView zuzugreifen, dann löst eine nicht abgefangene Ausnahme aus, die manchmal sagt 'Variable ist kein CFString' und manchmal bleibt sie bei' obj_msgsend' hängen, wenn ich den Debugger benutze und manchmal füllt sie einfach alle Tabellenzellen mit (weiter ..) –

+0

(Fortsetzung). ..) das letzte Objekt, das in das Array geschoben wurde! Das ist verrückt für mich. Könnten Sie bitte Licht darauf werfen? Und, danke für Ihre '@try \ @ catch' &' appendString' Vorschlag. Ich habe aufgenommen sie jetzt. –

+0

Sorry, ich glaube, ich habe es jetzt gerade gelöst. Ich denke, es war 'appendString' und folglich ändert' self.f_Name's Typ zu NSMutableString. Vielen Dank aBitObvious. –