UITableView Zelle memory-leak
Ich habe ein Leck in meinem tableview, dass ich das Auffüllen mit Daten.
Hier ist, was passiert:
Ich habe eine NSMutableArray
gefüllt mit NSDictionaries
(Kontaktdaten), dass ich das laden aus der sql-Datenbank jedes mal, wenn der Benutzer wählen Sie einen neuen index schreiben, das array ist gefüllt mit Informationen für die Kontakte.
Da bin ich mit einer Instanz-variable-Arrays, um die Daten aufzunehmen-ich vermute, so etwas wie dieses, bevor Sie jedes mal, wenn neue Daten vertauscht:
if (currentConnections != nil) {
[currentConnections release];
currentConnections = nil;
}
Würde effektiv loszuwerden, meine alten Daten, bevor ich es zurücksetzen.
Dies ist jedoch, wo die Fremdheit beginnt. In meinem tableView:cellForRowAtIndexPath:
ich Anrufe wie dieser:
NSString *firstname = [[currentConnections objectAtIndex:indexPath.row]
objectForKey:@"firstname"];
UILabel *name = [[UILabel alloc]
initWithFrame:CGRectMake(75, 12, 190, 15)];
name.font = [UIFont fontWithName:@"Gotham-Medium.ttf"
size:12];
name.textColor = [UIColor whiteColor];
name.backgroundColor = [UIColor clearColor];
name.text = firstname;
Wo aktuelle verbindungen ist die Reihe der Wörterbücher. Ich fügen Sie dann die UILabel
als eine Untersicht der Zelle:
[cell addSubview:name];
[name release];
Das Verhalten ist so:
Wenn ich ausführen als ist (die Freigabe der aktuellen verbindungen vor jeder swap dann das laden der neuen Daten) die app stürzt für einen bösen Fehler beim Zugriff.
Wenn ich nicht lassen Sie die Untersichten ich hinzufügen, um der Zelle die app nicht Abstürzen, aber ich sehe mit Entsetzen, wie live-bytes, die weiterhin zu akkumulieren in der memory-Allokationen Werkzeug, bis der Punkt, wenn ich switch contact info genug, dass ich eine memory Warnung, dann Absturz.
Scheint es mir, dass es einige seltsame Erinnerung Eigentumsfragen geht mit der Zelle und Untersichten. Ich tun geben Sie der Zelle als wiederverwendbare und ordnen Sie autorelease vor dem laden jeder mit Daten.
Irgendwelche Ideen was verursacht dieses Loch?
edit:
Dies ist die aktuelle tableView:cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
if (cell == nil) {
NSLog(@"within");
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
if (!ALOCATED) {
cellName = [[ UILabel alloc ]
initWithFrame:CGRectMake(75, 12, 190, 15)
];
cellName.font = [ UIFont
fontWithName:@"Gotham-Medium.ttf"
size:12
];
cellName.textColor = [ UIColor whiteColor ];
cellName.backgroundColor = [ UIColor clearColor ];
NSString *firstname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"firstname"
];
firstname = [ firstname stringByAppendingString:@" " ];
NSString *lastname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"lastname"
];
UIImage *profPic = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"profilepicture"
];
connectionPhoto = [[ UIImageView alloc ] initWithFrame:CGRectMake(10, 8, 56, 56) ];
connectionPhoto.image = profPic;
NSString *fullname = [ firstname stringByAppendingString:lastname ];
cellName.text = fullname;
[ cell addSubview:cellName ];
cellTitle = [[ UILabel alloc ]
initWithFrame:CGRectMake(75, 31, 260, 13)
];
cellTitle.font = [ UIFont
fontWithName:@"ArialMT"
size:10
];
cellTitle.textColor = [ UIColor whiteColor ];
cellTitle.backgroundColor = [ UIColor clearColor ];
cellTitle.text = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"title"
];
[ cell addSubview:cellTitle ];
[ cell addSubview:connectionPhoto ];
[ profPic release ];
ALOCATED = YES;
} else {
cellTitle.text = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"title"
];
connectionPhoto.image = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"profilepicture"
];
NSString *firstname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"firstname"
];
firstname = [ firstname stringByAppendingString:@" " ];
NSString *lastname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"lastname"
];
NSString *fullname = [ firstname stringByAppendingString:lastname ];
cellName.text = fullname;
}
return cell;
}
Wo ich bin, versuchen, zu erstellen eine Zelle und verwenden es, nur die änderung der Eigenschaften der Untersichten jeder Zeit.
BEARBEITEN
Was passierte war, dass ich das hinzufügen subviews der Zelle-Objekt selbst, das verursachte ein Leck, wie diese wurden nicht freigegeben. Sobald ich begann mit der Aussicht auf die UITableViewCell Mitglied Ansichten aka Zelle.contentView, Zelle.accessoryView etc... der Speicher wurde freigegeben. So wie daniel, die unten erwähnt werden, erstellen Sie einen benutzerdefinierten Zelle in der Tabelle und fügen Sie Ihre Ansichten auf die Zelle, die Eigenschaften oder fügen Sie Ihre Ansichten zum Mitglied uitablecellviews nicht die Zelle selbst. Die folgenden arbeitete für mich:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.accessoryType = UITableViewCellAccessoryNone;
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
UILabel *cName = [[ UILabel alloc ]
initWithFrame:CGRectMake(105, 10, 190, 15)
];
cName.font = [ UIFont
fontWithName:@"Gotham-Medium.ttf"
size:12
];
cName.textColor = [ UIColor whiteColor ];
cName.backgroundColor = [ UIColor clearColor ];
NSString *firstname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"firstname"
];
firstname = [ firstname stringByAppendingString:@" " ];
NSString *lastname = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"lastname"
];
NSString *fullname = [ firstname stringByAppendingString:lastname ];
cName.text = fullname;
[ cell.contentView addSubview:cName ];
[ cName release ];
cell.imageView.image = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"profilepicture"
];
UILabel *cTitle = [[ UILabel alloc ]
initWithFrame:CGRectMake(105, 25, 190, 13)
];
cTitle.font = [ UIFont
fontWithName:@"ArialMT"
size:10
];
cTitle.textColor = [ UIColor whiteColor ];
cTitle.backgroundColor = [ UIColor clearColor ];
cTitle.text = [[ currentConnections
objectAtIndex:indexPath.row
] objectForKey:@"title"
];
[ cell.contentView addSubview:cTitle ];
[ cTitle release ];
return cell;
}
- äh? wie fügen Sie ein NSString als Untersicht
- Ich habe gerade bearbeitet. oops ja, es war ein Etikett, das ich Hinzugefügt, wie die Untersicht
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie die Wiederverwendung von Zellen und jedes mal, wenn Sie setup eine Zelle, die Sie hinzufügen, UILabel, um es dann kann man sehen, wie viel UILabels zugewiesen werden, die dazu führen können Ihre Speicher-Problem...Wenn Sie möchten, fügen Sie eine Bezeichnung für die Zelle, Sie sollten nur müssen dies tun, wenn Sie Sie zuweisen, dann, wenn die Zelle kommt in eine Zelle wiederverwendet, es würde bereits enthalten, das UILabel, das Sie Hinzugefügt haben, so würden Sie nur zum Bearbeiten der Etiketten-text anstelle von hinzufügen eines neuen UILabel... das ist nur eine Vermutung von dem, was Sie geschrieben haben, etwas mehr code, vielleicht klären sich die Dinge...
Das problem ist offensichtlich aus dem code, den Sie geschrieben, Sie sind undicht die Zelle Instanz-variable, halten Sie auch im Verstand, dass
cellForRowAtIndexPath
aufgerufen wird, wird für jede Zeile in der Tabelle, so halten Sie eine Instanz-variable zu verfolgen, etwas Hinzugefügt, um die Zelle funktionieren nicht, die var wird weiterhin overwriten, aber in Ihrem Fall, dass Sie sind undicht Zellen. Sie sind das hinzufügen von Zellen an die UITableViewCell, nie loslassen und dann auf den nächsten Anruf zu cellForRowAtIndexPath den Zellen var bekommt overwriten und dem vorherigen Lecks, da Sie nicht über einen Weg zu lösen es nicht mehr...Sie können dieses Problem beheben, durch die Freigabe von Zellen...Jetzt haben Sie auch das Problem mit einer var zu verfolgen Etiketten auf Zellen, im Hinterkopf behalten, dass es nicht eine Zelle zugewiesen, die für die Wiederverwendung, das es wirklich so viele Zellen wie können anzeigen auf dem Bildschirm, so verfolgen eines var wird nicht funktionieren, ist Ihr Problem...Zu lösen, dass problem, ich würde Unterklasse UITableViewCell mit einer label-Eigenschaft und eine Methode zum zurücksetzen der label-text.
Hoffe, das hilft
in Ihrem code:
[ Zelle addSubview:Vorname ];
Vorname ist ein string...Sie können nicht hinzufügen ein NSString als Untersicht...und ich empfehle die Erstellung einer custom UITableviewcell, weil Zelle wiederverwertet werden, und wenn Sie ein Recycling-Zelle gibt es in allen Untersicht Hinzugefügt, während seine Schöpfung.