3 Stimmen

UITableView stürzt beim Scrollen ab

Ich habe versucht, meine eigene App für eine Band meiner Freunde zu erstellen, und ich habe mit der Verwendung einer benutzerdefinierten TableViewCell für Nachrichtenartikel, die auf der Website erscheinen, experimentiert. Mein Hauptziel ist es, alle Daten von der Website zu erhalten, speichern Sie es in einem NSMutableArray, und dann anzeigen, dass in meinem benutzerdefinierten Zellen.

Die App läuft gut, wenn sie die ersten 5-6 Zellen lädt. Wenn ich jedoch anfange zu blättern, stürzt die App ab. Ich habe den Fehler in der cellForRowAtIndexPath: Methode. Mit GDB habe ich auch herausfinden, dass, nachdem ich meine NSMutableArray Daten erstellen und sobald das Programm ausgeführt wird, nach dem Scrollen, mein Array scheint automatisch freigegeben werden. Ich bin nicht sicher, warum dies geschieht. Hier ist, was ich für meinen Code so weit haben:

In HomeViewController.h:

@interface HomeViewController : UIViewController {
    NSArray *results;
    NSMutableArray *titles;
    NSMutableArray *dates;
    NSMutableArray *entries;
}

@property (nonatomic, retain) NSMutableArray *titles;
@property (nonatomic, retain) NSMutableArray *dates;
@property (nonatomic, retain) NSMutableArray *entries;

@end

In HomeViewController.m:

- (void)viewDidLoad {
[super viewDidLoad];
titles = [[NSMutableArray alloc] init];
dates = [[NSMutableArray alloc] init];
entries = [[NSMutableArray alloc] init];

while((i+1) != endIndex){   
    NSString *curr_title = [[NSString alloc] init]; 
    NSString *curr_date = [[NSString alloc] init];
    NSString *curr_entry = [[NSString alloc] init];

    //do some character iterations across a string

    [titles addObject:curr_title];
    [dates addObject:curr_date];
    [entries addObject:curr_entry];

    [curr_title release];
    [curr_date release];
    [curr_entry release];
}
}

//weiterer Code hier, entfernt

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

static NSString *CellIdentifier = @"NewsCell";

NewsCell *cell = (NewsCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil) {
    NSArray *topLevelObjects = [[NSBundle mainBundle]
                                loadNibNamed:@"NewsCell"
                                owner:self options:nil];
//  cell = [topLevelObjects objectAtIndex:0];
    for(id currentObject in topLevelObjects){
        if([currentObject isKindOfClass:[UITableViewCell class]]){
            cell = (NewsCell *)currentObject;
            break;
        }
    }

}
NSLog(@"%d", indexPath.row);
NSLog(@"%d", titles.count);
cell.cellTitle.text = [titles objectAtIndex:indexPath.row];
cell.datePosted.text = [dates objectAtIndex:indexPath.row];
cell.preview.text = [entries objectAtIndex:indexPath.row];

return cell;
}

Auch hier werden die ersten 5-6 Zellen angezeigt. Sobald ich scrolle, habe ich versucht zu tun po titles und erhielt diesen Fehler:

Program received signal EXC_BAD_ACCESS, Could not access memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000009 0x011b309b in objc_msgSend ()

Ich habe versucht, die Arrays in initWithNibName: aber das scheint nicht viel gebracht zu haben. Ich habe versucht, den gesamten Code in viewDidLoad: und ruft dann [super viewDidLoad] und es führte zu den gleichen Ergebnissen. Tut mir leid, dass dies so lang ist, aber ich dachte, dass die Leute meinen Code sehen müssen.

2voto

titaniumdecoy Punkte 18400

Ich kann keinen offensichtlichen Fehler in dem von Ihnen geposteten Code erkennen. Versuchen Sie Aktivierung der Umgebungsvariablen NSZombieEnabled . Dadurch wird verhindert, dass Objekte freigegeben werden, so dass Sie bei einem "Absturz" Ihrer Anwendung feststellen können, welches Objekt das Problem verursacht hat.

Anstatt eine Schleife durch ein Array von Objekten zu ziehen, die von loadNibNamed:owner:options sollten Sie das gewünschte Objekt einem IBOutlet Eigenschaft Ihrer Klasse. Siehe Laden benutzerdefinierter Zellen in der Tabellenansicht aus Nib-Dateien für ein Beispiel.


Der folgende Text ist dem neuen Code entnommen, den Sie veröffentlicht haben:

NSString *curr_title = [[NSString alloc] init];

//do some character iterations across a string

[titles addObject:curr_title];

[curr_title release];

NSString ist nicht veränderbar (wie NSMutableString). Fügen Sie dem Titel-Array absichtlich leere Zeichenfolgen hinzu?


Als Antwort auf Ihren Kommentar: stringByAppendingString erzeugt ein neues, automatisch freigegebenes NSString-Objekt.

NSString *curr_title = [[NSString alloc] init];

// this leaks the original NSString object (curr_title no longer points to it);
// curr_title now points to a new, autoreleased NSString
curr_title = [curr_title stringByAppendingString:@"..."];

[titles addObject:curr_title];

// releasing the autoreleased NSString will cause your application to crash!
[curr_title release];

0voto

Leehro Punkte 561

Das Problem könnte mit der Implementierung von NewsCell, alle Ihre Eigenschaften dort beibehalten werden?

Auch, jeder Grund HomeViewController ist Subclassing UIViewController und nicht UITableViewController?

Und das sollte gut funktionieren:

NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil];
cell = [topLevelObjects objectAtIndex:0];

0voto

JoBu1324 Punkte 7703

*EXC_BAD_ACCESS* ist ein sicheres Zeichen dafür, dass eines Ihrer Objekte zu oft freigegeben wird (oder nicht richtig zurückgehalten wurde). NSZombieEnabled ist hier Ihr Freund, genau wie titaniumdecoy vorschlägt - herauszufinden, welches Objekt zu viel freigegeben wird, ist die halbe Miete. Stellen Sie nur sicher, dass Sie es vor der Freigabe der App ausschalten, weil (wie titaniumdecoy darauf hingewiesen) es verhindert, dass Objekte freigegeben werden.

In der Regel verwende ich eine Kombination aus NSZombieEnabled und gut platzierten Haltepunkten (so dass ich durch den Code gehen kann, bis er abstürzt), um herauszufinden, wo das Problem im Code auftaucht. Dann ist es in der Regel eine einfache Sache von Backtracking, um herauszufinden, wo das Objekt über freigegeben wurde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X