草庐IT

iphone - cellForRowAtIndexPath 内存管理

coder 2024-01-14 原文

所以,这是我的 cellForRowAtIndexPath 的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];
    }

    NSInteger artistIndex = 1; // 1
    NSInteger albumIndex = 3;  // 3
    NSInteger dateIndex = 6;   // 6
    NSInteger imageIndex = 8;  // 5

    // ARTIST
    CGRect frame = CGRectMake(59, 11, 244, 13);
    UILabel *label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont boldSystemFontOfSize:13];
    label.textColor = [UIColor blackColor];
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:artistIndex];
    [cell addSubview:label];

    // ALBUM (more like description...
    frame = CGRectMake(60, 30, 244, 11);
    label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont boldSystemFontOfSize:11];
    label.textColor = [UIColor darkGrayColor];
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:albumIndex];
    [cell addSubview:label];

    // DATE
    frame = CGRectMake(59, 49, 244, 10);
    label = [[UILabel alloc]initWithFrame:frame];
    label.font = [UIFont fontWithName:@"Helvetica" size:10.0];
    label.textColor = [UIColor darkGrayColor];
    label.textAlignment = UITextAlignmentRight;
    label.text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:dateIndex];
    [cell addSubview:label];

    // IMAGE
    UIImageView *imageView = [[UIImageView alloc]init];
    imageView.image = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:imageIndex];
    imageView.frame = CGRectMake(8,9,44,44);
    [imageView.layer setMasksToBounds:YES];
    [imageView.layer setCornerRadius:3.0];
    [[cell contentView] addSubview:imageView];

    [imageView release];
    [label release]; 

    return cell;
}

为了解释发生了什么,基本上它只是利用一个数组来存储除索引 8(存储 UIImage)之外的所有内容的字符串。

我没有设置自动释放变量(主要是因为我还不太了解自动释放,哈哈)

无论如何,当在应用程序中滚动时,它会逐渐变慢(主要是因为 UIImage,但也部分是因为标签和框架)。

有没有办法更好地管理我的内存?另外,有没有更好的编码方式?我正在考虑制作一个 UITableViewCells 数组,然后通过 cellForRowAtIndexPath 访问它们。

所以我很乐意提供一些建议,谢谢大家。

最佳答案

你在那里泄露了很多标签。每次您分配/初始化一个新标签时,您都需要释放它。目前,您通过为它分配一个新的标签对象而不释放旧的标签对象来多次重复使用同一个标签变量。

不要将 [label release] 放在末尾,而是将 [label release] 放在每个 [cell addSubview:label] 之后;

您的下一个问题是您误解了表格单元格回收的工作原理。 UITableCell 对象在表格中一遍又一遍地重复使用,这就是为什么要这样做:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];
}

这基本上是在说“检查是否有可用的单元格,如果没有则创建一个新单元格”。当一个单元格被重新使用时,它会保留你添加到其中的所有旧内容。因此,当您将这些标签和 ImageView 添加到单元格时,它们将在下次使用时保留在该单元格中,并在下一次使用。

但是因为每次重新使用单元格时都会再次添加标签,它会建立标签的多个副本,所以第二次显示单元格时,它的标签数量是原来的两倍,而下一次是标签数量的 3 倍许多,等等。您看不到重复项,因为它们位于完全相同的位置,但它们在那里会耗尽内存并减慢您的表速度。

您需要在“if (cell == nil) { ... }”语句中移动将新 View 附加到单元格的代码,以便在创建单元格时仅添加一次标签。

当然,这意味着每个单元格都将具有相同的文本和图像,这是您不想要的,因此您需要拆分设置文本和图像的逻辑并将其放在 if 语句之后。这样您只需创建一次标签,但每次它们显示在不同的表格行中时您都会设置文本。这有点棘手,因为您不再有对标签的引用,但您可以通过在标签上设置唯一标签来实现,这样您就可以再次找到它们。

这是一个清除了所有漏洞的清理版本:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"identifier"];

    NSInteger artistTag = 1;
    NSInteger albumTag = 2;
    NSInteger dateTag = 3;
    NSInteger imageTag = 4;

    if (cell == nil) {

        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"identifier"]autorelease];

        // ARTIST
        CGRect frame = CGRectMake(59, 11, 244, 13);
        UILabel *label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont boldSystemFontOfSize:13];
        label.textColor = [UIColor blackColor];
        label.tag = artistTag;
        [cell addSubview:label];
        [label release];

        // ALBUM (more like description...
        frame = CGRectMake(60, 30, 244, 11);
        label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont boldSystemFontOfSize:11];
        label.textColor = [UIColor darkGrayColor];
        label.tag = albumTag;
        [cell addSubview:label];
        [label release];

        // DATE
        frame = CGRectMake(59, 49, 244, 10);
        label = [[UILabel alloc]initWithFrame:frame];
        label.font = [UIFont fontWithName:@"Helvetica" size:10.0];
        label.textColor = [UIColor darkGrayColor];
        label.textAlignment = UITextAlignmentRight;
        label.tag = dateTag;
        [cell addSubview:label];
        [label release];

        // IMAGE
        UIImageView *imageView = [[UIImageView alloc]init];
        imageView.frame = CGRectMake(8,9,44,44);
        imageView.tag = imageTag;
        [imageView.layer setMasksToBounds:YES];
        [imageView.layer setCornerRadius:3.0];
        [[cell contentView] addSubview:imageView];
        [imageView release];
    }

    NSInteger artistIndex = 1; // 1
    NSInteger albumIndex = 3;  // 3
    NSInteger dateIndex = 6;   // 6
    NSInteger imageIndex = 8;  // 5

    ((UILabel *)[cell viewWithTag:artistTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:artistIndex];

    ((UILabel *)[cell viewWithTag:albumTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:albumIndex];

    ((UILabel *)[cell viewWithTag:dateTag]).text = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:dateIndex];

    ((UIImageView *)[cell viewWithTag:imageTag]).image = [[musicList.list objectAtIndex:indexPath.row] objectAtIndex:imageIndex];


    return cell;
} 

关于iphone - cellForRowAtIndexPath 内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8859735/

有关iphone - cellForRowAtIndexPath 内存管理的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - i18n Assets 管理/翻译 UI - 2

    我正在使用i18n从头开始​​构建一个多语言网络应用程序,虽然我自己可以处理一大堆yml文件,但我说的语言(非常)有限,最终我想寻求外部帮助帮助。我想知道这里是否有人在使用UI插件/gem(与django上的django-rosetta不同)来处理多个翻译器,其中一些翻译器不愿意或无法处理存储库中的100多个文件,处理语言数据。谢谢&问候,安德拉斯(如果您已经在ruby​​onrails-talk上遇到了这个问题,我们深表歉意) 最佳答案 有一个rails3branchofthetolkgem在github上。您可以通过在Gemfi

  3. ruby-on-rails - Ruby 中的内存模型 - 2

    ruby如何管理内存。例如:如果我们在执行过程中采用C程序,则以下是内存模型。类似于这个ruby如何处理内存。C:__________________|||stack|||------------------||||------------------|||||Heap|||||__________________|||data|__________________|text|__________________Ruby:? 最佳答案 Ruby中没有“内存”这样的东西。Class#allocate分配一个对象并返回该对象。这就是程序

  4. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

    我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

  5. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  6. ruby - (Ruby || Python) 窗口管理器 - 2

    我想用这两种语言中的任何一种(最好是ruby​​)制作一个窗口管理器。老实说,除了我需要加载某种X模块外,我不知道从哪里开始。因此,如果有人有线索,如果您能指出正确的方向,那就太好了。谢谢 最佳答案 XCB,X的下一代API使用XML格式定义X协议(protocol),并使用脚本生成特定语言绑定(bind)。它在概念上与SWIG类似,只是它描述的不是CAPI,而是X协议(protocol)。目前,C和Python存在绑定(bind)。理论上,Ruby端口只是编写一个从XML协议(protocol)定义语言到Ruby的翻译器的问题。生

  7. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  8. ruby-on-rails - 事件管理员和自定义方法 - 2

    这是我在ActiveAdmin中的自定义页面ActiveAdmin.register_page"Settings"doaction_itemdolink_to('Importprojects','settings/importprojects')endcontentdopara"Text"endcontrollerdodefimportprojectssystem"rakedataspider:import_projects_ninja"para"OK"endendend我想做的是,当我单击“导入项目”按钮时,我想在Controller中执行rake任务。但是我无法访问该方法。可能是什

  9. ruby-on-rails - HTTParty 的内存问题和下载大文件 - 2

    这会导致Ruby出现内存问题吗?我知道如果大小超过10KB,Open-URI会写入TempFile。但是HTTParty会在写入TempFile之前尝试将整个PDF保存到内存吗?src=Tempfile.new("file.pdf")src.binmodesrc.writeHTTParty.get("large_file.pdf").parsed_response 最佳答案 您可以使用Net::HTTP。参见thedocumentation(特别是标题为“流媒体响应机构”的部分)。这是文档中的示例:uri=URI('http://e

  10. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

随机推荐