2009-08-03 13 views
0

Ich habe meinen Code vereinfacht, um mit zu testen, und immer noch auf dem Telefon steigt meine Speicherbelegung bis zu einem Punkt, wo der Tisch langsam abbremst.Warum werden keine Tablezellen freigegeben?

Kann mir jemand sagen, was ich hier falsch mache?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return 40; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return 100; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *cellID = @"Cell"; 
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease]; 
    } 
    UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)]; 
    l.font=[UIFont boldSystemFontOfSize:15]; 
    l.textColor=[UIColor whiteColor]; 
    l.backgroundColor=[UIColor blackColor]; 
    [email protected]"Just some randoom text here"; 
    [cell.contentView addSubview:l]; 
    [l release]; 

Oops. Diese Code-Paste hat nicht so gut funktioniert. Hier ist eine gerade Paste:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return 40; 
} 


- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return 100; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *cellID = @"Cell"; 
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease]; 
    } 
    UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)]; 
    l.font=[UIFont boldSystemFontOfSize:15]; 
    l.textColor=[UIColor whiteColor]; 
    l.backgroundColor=[UIColor blackColor]; 
    [email protected]"Just some randoom text here"; 
    [cell.contentView addSubview:l]; 
    [l release]; 
     return cell; 
} 

Antwort

0

Sie Recycling UITableViewCell Instanzen, aber du bist immer noch eine neue UILabel Instanz für jede Zeile Erstellen und Hinzufügen zu jeder einzelnen Zelle. Hier kommt die Speicherbelegung her. Probieren Sie etwas wie folgt aus:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *cellID = @"Cell"; 
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease]; 
     UILabel *l=[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)]; 
     l.font=[UIFont boldSystemFontOfSize:15]; 
     l.textColor=[UIColor whiteColor]; 
     l.backgroundColor=[UIColor blackColor]; 
     [email protected]"Just some randoom text here"; 
     [cell.contentView addSubview:l]; 
     [l release]; 
    } 
    return cell; 
} 
1

Sie ein Muster wie diese folgen möchten:

#define kTagMyLabel 1 

- (UITableViewCell *)tableView:(UITableView *)tableView 
     cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *cellID = @"Cell1"; 
    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellID]; 
    UILabel * l; 
    if (cell == nil) { 
    // create the cell 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:cellID] autorelease]; 

    // perform setup/functions that are common to all cells 
    l = [[[UILabel alloc] initWithFrame:CGRectMake(10,10,300,16)] autorelease]; 
    l.font=[UIFont boldSystemFontOfSize:15]; 
    l.textColor=[UIColor whiteColor]; 
    l.backgroundColor=[UIColor blackColor]; 
    l.tag = kTagMyLabel ; 
    [cell.contentView addSubview:l]; 
    } 
    else 
    { 
    // find the label we previously added. 
    l = (UILabel*)[cell viewWithTag:kTagMyLabel]; 
    } 

    // now set up the cell specific to this indexPath 
    [email protected]"Just some random text here"; 
    return cell; 
} 
+0

Leider pegs Speicher mit dieser Lösung auch (gerade kopieren und einfügen). Vielleicht ist es die Art, wie die Tabellenansicht platziert wird. Ich habe den Tabbar-Controller in IB erstellt und die View-Controller auch in IB zugewiesen. Also vielleicht hat der Autorespulepool nie eine Chance zu veröffentlichen? Was wäre ein besserer Weg? Und sollte ich einen NSAutoreleasePool irgendwo anders als main setzen, um das freizugeben? Wenn ja, wenn die Ansicht selbst, die sich an der Tabbarposition befindet, nicht freigegeben wird? –

+0

Ich weiß nicht, ob das irgendwas bedeutet, aber der Speicher ist im Simulator richtig frei. –

+0

Der Pool wird nach jedem UI-Ereignis gelöscht. Was * genau * wird nicht veröffentlicht? Wann sehen Sie einen Speicherverlust? Ist es, wie Sie eine lange Liste von Elementen nach unten scrollen, und dann wieder aus Ihrem Viewcontroller? Sie haben dann irgendwo ein Leck. – Jason

0

Da jeder UITableViewCell einen eigenen Standard UILabel (cell.textLabel) hat, tun Sie wirklich, dass zusätzliche Etikett benötigen zum ContentView hinzugefügt? Wenn Sie benutzerdefinierte Zellen benötigen, sollten Sie die Unterklasse UITableViewCell in Betracht ziehen.

+0

Das Beispiel, das ich gab, war nur eine gepaarte Version. In meinem echten Code unterteile ich UITableviewCell und füge mehrere Felder und ein Bild hinzu. –

Verwandte Themen