【问题标题】:release NSData in NSManagedObject在 NSManagedObject 中释放 NSData
【发布时间】:2011-01-08 08:11:16
【问题描述】:

我使用数据模型来存储 2 个对象:视频、图像。 视频仅包含字符串属性,图像具有 2 个“二进制数据”属性。

一开始,2 个二进制数据属性位于视频对象中。 但是所有视频都是在 UITableView 初始化期间加载的。 对于 400 个视频,二进制数据代表 20 Mo,所以想象一下 4000 个视频...

现在有 2 个对象,UITableView 加载工作正常。 我在方法中需要时加载二进制数据:tableView:cellForRowAtIndexPath

但现在我滚动到列表中的次数越多,内存就越长:(

看看我的方法:

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

    static NSString *CellIdentifier = @"videoCell";
    Video *theVideo = (Video *)[[self fetchedResultsController] objectAtIndexPath:indexPath];
    VideoCellViewController *cell = (VideoCellViewController *)[myTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"VideoCellView" owner:self options:nil];
        cell = editingTableViewCell;
        self.editingTableViewCell = nil;
    }
    cell.video = theVideo;
    return cell;
}

以及VideoCellViewController中的setvideo方法

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
    }
    NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
    UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
    smallImage.image = uiImage;
    nameLabel.text = video.displayName;
    [uiImage release];
}

即使没有设置 smallImage,我也有内存问题。 如果我加载图像对象,它永远不会释放。

我尝试了很多解决方案来释放内存但没有成功...( didTurnIntoFault, release, CFRelease...) 在性能工具中,我可以看到我的二进制数据为 CFData。

我使用了很多 iPhoneCoreDataRecipes 和 PhotoLocations 示例。

我需要帮助来清理我的记忆;)

谢谢

塞缪尔

【问题讨论】:

  • editingTableViewCell 来自哪里?

标签: iphone database memory-management core-data nsdata


【解决方案1】:

很明显,您的表格单元格创建逻辑发生了一些事情。我们先来看一个典型的cellForRow委托处理程序..

static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
     cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
}
// do stuff with cell
return cell;

我们看到了

  • 试图获得可重复使用的单元格
  • 如果失败(nil)创建一个新的并将可重用的 id 传递给 ctor
  • 然后对单元格(新的或现有的)进行处理并返回它

如果您没有在表格视图中键入单元格以供重复使用,您将始终从出队返回一个“nil”单元格,因此每次都需要创建新单元格。这将导致内存在您滚动时继续增长,但在空闲时保持相当平坦。

编辑:

假设您的单元格没有问题,那么您需要缩小范围是视频数据还是图像数据泄漏。 smallImage 是什么?你确定你不想只在视频是新的时候才做所有事情吗?

- (void)setVideo:(Video *)newVideo {
    if (newVideo != video) {
        [video release];
        video = [newVideo retain];
        NSData *imageData = [video.allImages valueForKey:@"thumbnailImage"];
        UIImage *uiImage = [[UIImage alloc] initWithData:imageData];
        smallImage.image = uiImage;
        nameLabel.text = video.displayName;
        [uiImage release];
    }
}

【讨论】:

  • 单元重用在我的项目中运行良好(我在 nib 文件中定义了 cellIdentifier)。通过日志,我只看到了 8 个单元格的创建。我真的认为这是二进制数据发布的问题。
  • 感谢您的帮助 ;) smallImage 是在 nib 中定义的 UIImageView。但即使没有设置 smallImage 我也有内存问题:(只是 valueForKey 制造麻烦。之后它永远不会释放......也许我必须告诉 NSManagedObjectContext 暂时抑制内存中的对象。
  • 您是否在dealloc 块中发布视频?
  • 我想我必须看到更多你的代码来帮助你完成这个
  • 也许解决方案是将图像存储到文件而不是数据库中。喜欢:stackoverflow.com/questions/1015713/…
猜你喜欢
  • 1970-01-01
  • 2013-06-08
  • 2012-05-22
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 2012-09-15
相关资源
最近更新 更多