2009-04-03 12 views
0

Ich versuche einen UITableViewController (Delegate & dataSource für die Ansicht) zu verwenden, um eine einfache Tabelle anzuzeigen, die von einem Plist gelesen wird. Das Plist enthält ein NSDictionary, das selbst mehrere NSDictionary-Objekte enthält, die Objekte darstellen, die in meiner Anwendung verwendet werden.EXC_BAD_ACCESS in UITableViewController

Der Rest des Codes sieht wie folgt aus etwas (vereinfacht):

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    [self loadObjectsFromPlist]; 
} 

- (void)loadObjectsFromPlist { 
    NSString *objectPlistFile = [[NSBundle mainBundle] pathForResource:@"Objects" ofType:@"plist"]; 
    NSDictionary *objectsDictionary = [NSDictionary dictionaryWithContentsOfFile:objectsPlistFile]; 

    objects = [[NSMutableArray alloc] init]; 
    NSEnumerator *objectEnumerator = [objectsDictionary objectEnumerator]; 
    NSDictionary *objectData; 
    while(objectData = [objectEnumerator nextObject]) { 
     [objects addObject:[MyObject objectFromDictionary:objectData]]; 
    } 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [objects count]; 
} 

Da ich alle Abschnitte nicht verwende ich 1 in numberOfSectionsInTableView des Controllers zurück.

Die objectFromDictionary Methode von "MyObject" weist die Daten, die von NSDictionary gelesen werden, einem neuen Objekt zu. Ich versuchte es auch zu behalten, zu kopieren, aber daran änderte sich nichts.

Ich bekomme eine EXC_BAD_ACCESS in tableView:numberOfRowsInSection beim Aufruf [objects count]. Ich habe versucht, das Object Allocation Instrument zu verwenden, aber ich habe kein Problem gefunden. Mein Plist enthält derzeit nur Daten für ein Objekt. Der Debugger zeigt für das Attribut objects "1 Objekte" in roter Farbe an, daher denke ich, dass dies mit dem Problem zusammenhängt.

+0

Eine Anmerkung ist, dass die rote Farbe für die Variable "1 objects" im Debugger einfach bedeutet, dass der Wert geändert wurde, als die Anwendung zuletzt aktiv war. (ZB. Etwas wurde hinzugefügt oder entfernt.) –

+0

Ah ok ... danke für das Löschen. Das hängt also nicht mit meinem Problem zusammen und macht es noch kryptischer für mich. – Koraktor

+0

Könnte nur ein Übertragungsfehler sein, aber Sie haben [Objekt addObject: [MyObject ..., und es sollte wahrscheinlich sein [Objekte addObject ... –

Antwort

0

Ok, nachdem ich alle deine Antworten durchgelesen und versucht habe, meinen Fehler zu finden, habe ich meinen Code fast komplett neu geschrieben. Schließlich habe ich die Debug-Ausgabe entfernt, die ich hinzugefügt habe, als der Fehler zum ersten Mal auftrat.

NSLog(@"Object count: %@", [objects count]); 

Als NSArray ‚s count kein Objekt, sondern eine ganze Zahl zurückgibt diese offensichtlich falsch ist und sein sollte:

vor, ohne diese Linie
NSLog(@"Object count: %u", [objects count]); 

Dennoch ist die EXC_BAD_ACCESS aufgetreten, aber es scheint, es verlangsamte mein Debugging. ;) Leider kann ich das eigentliche Problem jetzt nicht reproduzieren.

Was ich sagen kann: Der Fehler war nicht das Ergebnis eines Timing-Problems. Ich habe das jetzt gleich überprüft.

+0

Wenn Sie eine EXC_BAD_ACCESS erhalten, gehen Sie zur Konsole und geben Sie "bt" ein, um eine Stack-Trace zu erhalten. könnte für Sie nützlich sein und auch für Leute, die versuchen, Ihnen zu helfen. – siukurnin

0

Es klingt, als würde es numberOfRowsInSection aufrufen, bevor loadObjectsFromPlist aufgerufen wird.

Wenn Sie Ihren Controller programmatisch laden, versuchen Sie vielleicht, loadObjectsFromPlist von initWithFrame aufzurufen: Style: statt viewDidLoad.

Wenn ich einen Mac vor mir hätte, würde ich es selbst machen, aber Sie könnten versuchen, Breakpoints zu setzen und herauszufinden, in welcher Reihenfolge diese Methoden aufgerufen werden. NSLog Aussagen über den ganzen Ort funktionieren auch.

+0

Ich habe dies bereits mit dem Debugger überprüft. Wie bereits erwähnt, zeigt der Debugger sogar die Daten aus dem Plist an (obwohl rot). – Koraktor

1

Wenn der Debugger zeigt, dass der EXC_BAD_ACCESS bei [servers count] auftritt, wird der (angenommene) ivar servers richtig initialisiert? Ich habe in Ihrem Beispielcode keinen Verweis darauf gefunden.

+0

Oh, tut mir leid. Ich habe vergessen, das in meinem Text umzubenennen. Ich habe versucht, den Code auf ein Minimum zu reduzieren und änderte auch die Variablennamen, um allgemeiner zu sein. In meinem realen Projekt heißt die Variable "servers", aber sie wird wie im Code-Beispiel meiner Frage als "Objekte" initialisiert. – Koraktor

2

, dass die Daten, um sicherzustellen, zu gegebener Zeit geladen wird, versuchen faul Initialisierung:

- (NSArray *)objectsFromPlist { 
    if (!objects) { 
     ... // initialize once here 
    } 
    return objects; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [[self objectsFromPlist] count]; 
} 
1

Was objects ist? Können Sie Ihre Header-Datei anzeigen? Es könnte mir ein besseres Verständnis geben. Haben Sie auch versucht, [super viewDidLoad] nach Ihrer [self loadObjectsFromPlist] zu setzen? Es scheint wie ein Timing-Problem, oder objects wird bei einem Unfall in einer Ihrer Methoden veröffentlicht.

+0

Nein, das habe ich schon probiert. Stürzt immer noch ab. – Koraktor

+0

Versuchen Sie, Ihre PLIST-Ladung zu überspringen und legen Sie einfach Objekte = [[NSMutableArray alloc] init]; vor der [super viewDidLoad]. Wenn das Problem gelöst wird, bestätigt dies, dass ein Timing-Problem vorliegt. – Jab

+0

Das funktioniert. Aber wie kann ich das wirklich lösen? – Koraktor

0

Es ist möglich, dass Sie Ihre UITableViewController freigegeben haben, was bedeutet, dass das Mitglied objects nicht mehr gültig ist. Stellen Sie sicher, dass Sie irgendwo einen Verweis auf die UITableViewController halten. Eine einfache Möglichkeit zu überprüfen, ob dies der Fall ist, ist das Hinzufügen eines [self retain] Anrufs in Ihrer viewDidLoad Methode (vorübergehend!). Wenn das Problem dadurch beseitigt wird, müssen Sie überprüfen, wem der Controller gehört, und sicherstellen, dass er ihn nicht freigegeben hat.

EDIT: Ich denke, ein besserer Weg zu testen wäre, einen Haltepunkt in Ihre Dealloc-Methode zu setzen.

+0

Das hat nicht funktioniert. Stürzt immer noch mit [self retain] in viewDidLoad ab. – Koraktor

+0

Ich habe einen Breakpoint zum Dealloc meiner Objekte hinzugefügt ... es wird nie aufgerufen. – Koraktor

1

Meine Vermutung ist, dass Sie möglicherweise Ihren gesamten (relevanten) Code, nicht eine abgespeckte Version veröffentlichen müssen. Ohne zu wissen, was Sie sonst noch tun können, sowohl im Code als auch im Pliste, wird es schwer sein, das herauszufinden ...wir feuern alle blind hier ab (zugegebenermaßen kein ungewöhnliches Vorkommnis auf SO ;-)

+0

Das hätte mein Problem wahrscheinlich schneller gelöst. Ich werde versuchen, mich daran zu erinnern. ;) – Koraktor

0

Setzen Sie Ihre [self loadObjectsFromPlist] vor [super viewDidLoad]. Ihre "Objekte" Variable wird nie initialisiert, weshalb Sie einen Fehler EXEC_BAD_ACCESS erhalten.

+0

Dies wurde bereits von Jesse Brown erwähnt und hat nicht funktioniert. – Koraktor