2009-08-06 9 views
1

Ich habe die folgende Methode:Unexpected EXC_BAD_ACCESS in Objective-C

-(void)testAPIModule { 
    self.requests = [NSMutableArray array]; 
    NSLog(@"making arrays"); 
    /*(A)*/ id array1 = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithFloat:2], nil]; 
    /*(B)*/ id array2 = [NSArray arrayWithObjects:[NSNumber numberWithInt:4], [NSNumber numberWithInt:5]]; 
    NSLog(@"made array=%@",array2); 

    for(ServerRequest *req in self.requests) { 
     [Networker sendRequest:req withDelegate:self]; 
     [req release]; 
    } 
} 

Der Code wie erwartet läuft.

Allerdings, wenn ich Zeile (A) auskommentieren ODER die ", Null" am Ende davon entfernen, bekomme ich einen EXC_BAD_ACCESS Fehler in Zeile (B)! Dem Debugger zufolge tritt der Fehler in CFRetain in dem integrierten Konstruktor + [NSArray arrayWithObjects] auf.

Zusätzlich, wenn ich Zeile (A) kommentieren und die for (...) Schleife auskommentieren, durchläuft der Code die Methode.

Das ist sehr unerwartet für mich. Was mache ich falsch online (B)? Und warum würde das Erstellen eines komplett anderen Arrays in Zeile (A) die Methode durchlaufen lassen? Und warum verhindert das Auskommentieren der For (...) -Schleife den Fehler in der Zeile (B) davor?

Kann jemand erklären, warum das ist? Oder gib mir wenigstens einen Tipp zum Debuggen? Ich habe bereits verifiziert, dass die Methode nur einmal ausgeführt wird und dass "Selbst" gültig ist.

Antwort

3

Wenn Sie die Komfortmethode arrayWithObjects verwenden, müssen Sie als letztes Element nil angeben.

Dokumentation sagt:

arraywithobjects:

Erstellt und gibt ein Array der Objekte in der Argumentliste enthält.

+ (id)arrayWithObjects: (id)firstObj, ...

Parameter

firstObj, ...
Eine durch Kommata getrennte Liste von Objekten mit Null enden.

+0

Nun, das ist neu für mich. Vielen Dank. Obwohl ich immer noch keine Ahnung habe, warum Linie B funktioniert hat, als Linie A ihr vorausging. Ich denke, es ist nur mit Müll gefüllt, der zufällig mit einem NSArray * -Zeiger ausgerichtet wurde? – tba

+0

Wahrscheinlich, weil der Fehler aufgetreten ist, wenn Sie über Zeile A hinausgehen. Nicht sicher, warum Zeile B überhaupt funktioniert hätte - es sollte definitiv auch ein Problem verursachen. –

+3

Alles hängt davon ab, was auf dem Stapel zu der Zeit ist. Es ist sehr wahrscheinlich, dass die Null von Linie A noch immer auf dem Stapel für Linie B war, also hatten Sie Glück. – kperryua

1

Fügen Sie -Wormat zu Ihren anderen Warnflags hinzu und der Compiler wird das fehlende Nil für Sie abholen.

Die zweite arbeitet nach der ersten, weil die Elemente alle auf der gleichen Position auf dem Stapel sind. Nach der Rückkehr von der ersten enthält der Stapel immer noch einen Zeiger auf [NSNumber numberWithInt:1], einen Zeiger auf [NSNumber numberWithFloat:2] und Null (und diese Zeiger sind sogar noch gültig, da der Autorelease-Pool noch nicht geleert wurde!). Wenn Sie die zweite ohne die Null aufrufen, ersetzt sie die Zeiger auf dem Stapel, aber die Null bleibt unverändert. Wenn Ihr zweiter Versuch drei Nummern gehabt hätte, wäre er wahrscheinlich auf die gleiche Weise abgestürzt, da die dritte Zahl die Null überschrieben hätte und dann die nächste Zahl übrig geblieben wäre.