2009-06-30 3 views
1

Ich habe eine Device/Debug-Build, die gut funktioniert. Wenn ich für die Freigabe zu bauen und auf das Gerät verteilen, bekomme ich diesen Fehler:Warum schlägt die Erstellung von Releases fehl und debuggt nicht?

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UILabel setWidth:]: unrecognized selector sent to instance 0x1605a0' 

Es wird in cellForRowAtIndexPath vorkommen:

cell.videoName.width = 163.0; 

wo Zelle eine benutzerdefinierte UITableViewCell und videoName ein UILabel ist. Warum sollte der Debug-Build funktionieren und die Freigabe fehlschlagen? Die Verteilungserstellung schlägt ebenfalls fehl. Alle sind für Base SDK == iPhone OS 3.0 eingestellt.

Um eine Version auf dem Telefon zu erstellen, ändere ich einfach meine Code-Signierung zu Entwickler. Ich habe auch versucht, die Distribution über iTunes zu erstellen, aber es schlägt mit dem gleichen Fehler fehl.

--- edit ---

ich die Zelle wie das Laden:

static NSString * QuestionCellIdentifier = @"QuestionCellIdentifier"; 
TopicCellController *cell = (TopicCellController *)[tableView dequeueReusableCellWithIdentifier:QuestionCellIdentifier]; 

if(cell == nil){ 
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"TopicCell" owner:self options:nil]; 
    cell = [nib objectAtIndex:0]; 
} 

cell.videoName.width = 163.0; 

Zur Laufzeit ist die Zelle des benutzerdefinierten Typ und videoName ist nicht gleich Null. Wenn ich die letzte Zeile (Einstellungsbreite) entferne, funktioniert es gut.

--- Edit: Neuentdeckung ---

Ich habe festgestellt, dass anstatt Breite aufrufen, kann ich dies tun und es funktioniert in Release:

cell.videoName.frame = CGRectMake(10, 10, 100, 30); 

Das ist wirklich nicht machen irgendein Sinn.

Antwort

0

Es hört sich so an, als hätten Sie entweder einen Debug-Code (Tracing mit NSLog?), Der Nebenwirkungen hat, oder Sie haben einen intermittierenden Race-Zustand zwischen Threads, der nur im schnelleren Release-Build erscheint.

Also würde ich zuerst für debug-abhängigen Code überprüfen und dann, wenn Sie Hintergrundthreads haben, überprüfen Sie, ob sie die Zelle beeinträchtigen könnten.

Es könnte auch ein Fehler in Ihrer CellForRowAtIndexPath-Wiederverwendungs-Bezeichnerverarbeitung sein, die manchmal zu einem Null führt - aber es ist schwer zu verstehen, warum dies nur in Release-Builds passieren würde. Ohne zu sehen, wie Ihre benutzerdefinierte Zelle eingerichtet ist, ist es schwierig, mehr zu kommentieren.

+0

Ich habe in bearbeitet einige zusätzliche Informationen zu Ihren Kommentaren. Vielen Dank. – 4thSpace

1

Meiner Erfahrung nach ist dies normalerweise, weil der zugeordnete Speicher in einem Debug-Build auf 0x00 initialisiert wird und nicht in einem Release-Build. Daher hat eines der Mitglieder Ihrer Datenstruktur im Release-Build einen Selektor, der von etwas anderem übrig geblieben ist. Im Debug-Build ist es auf Null gesetzt.

Aber ich weiß nicht, ob die iPhone SDK Umgebung Speicher auf Nullen initialisiert - es scheint, dass mehr moderne Entwicklungsumgebungen in einem Debug-Build neu zugeordneten Speicher zu etwas wie 0xcd statt 0x00 initialisieren.

Auch Sie könnten this StackOverflow question.

+0

Der von Ihnen angegebene Link ist für Visual Studio. Beachten Sie, dass dies iPhone/Xcode ist. – 4thSpace

+1

Ja, der Link ist für Visual Studio, aber die Konzepte sind ähnlich, wenn nicht gleich. –

+0

Danke für diese Antwort @Jared. +1 Wir sind in einem aktuellen Projekt auf dieses Problem gestoßen, bei dem ein Teammitglied einige int-Variablen nicht initialisiert hat. – dredful

0

Es überprüfen möchten sein sollte:

cell.videoName.frame.size.width = 163.0; 

UILabel keine Breite Eigenschaft haben, hat es eine Rahmen Eigenschaft mit einer Breite Feld.

0

auch der Grund, warum es in Release und nicht in debug Fehler ist, dass Release einige Ziel Build-Einstellung, die anders als debug ist, sehen, welche sind unterschiedlich. Normalerweise hat Release mehr Optimierungen im Gange. und das wird den Fehler in Ihrer App sehen (wie Code in Inline), wo Ihr Fehler im Standardziel zufällig einen guten Punkt im Speicher sieht, durch Pech seinerseits (oder ein leerer Fleck oder nur ein Fleck, der zufällig ist) eine Integer darin, und das ist, was Sie erwartet haben), die die Ausnahme nicht auslösen wird, wo Inlining bewegt den Code, so dass Ihr Fehler jetzt Zugriff auf einen anderen Speicherort im Speicher ..