如何在不创建内存泄漏的情况下为UITableViewCell分配资源

时间:2013-02-18 23:21:11

标签: uitableview avplayer

我有一个UITableView,我正在添加单元格。每个单元格包含图像,标题和AVPlayer。我正在实施如下

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

    static NSString *CellIdentifier = @"MyCell";
    VideoFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
    }
    NSDictionary *row = [myobj  objectAtIndex:indexPath.row];

    AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
    AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
    playerLayer.frame = CGRectMake(0.0, 0.0, 300.0, 300.0);       
    player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
    [cell.myViewContainer.layer addSublayer:playerLayer];
    return cell
}

我担心的原因有很多,为每个单元创建一个AVPlayer似乎会占用大量的内存。我也不清楚dequeueReusableCellWithIdentifier:CellIdentifier是如何工作的。如果我在这个中间抛出一个NSLog,每次我上下滚动都会调用它,这让我相信我也创建了一个新的AVPlayer实例,这就像一个巨大的内存泄漏。基本上,如何正确地执行此操作,分配一个类(如AVPlayer)以在UITableviewCell中使用,但请确保在下次调用cellForRowAtIndexPath时不重新分配它。

2 个答案:

答案 0 :(得分:1)

您需要在if (cell == nil)块中放置任何alloc代码。所以拿你的代码,试试这个:

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

    static NSString *CellIdentifier = @"MyCell";
    VideoFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
        AVPlayer *player = [AVPlayer playerWithPlayerItem:playerItem];
        AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:player];
        playerLayer.frame = CGRectMake(0.0, 0.0, 300.0, 300.0);       
        player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
        [cell.myViewContainer.layer addSublayer:playerLayer];
    }
    NSDictionary *row = [myobj  objectAtIndex:indexPath.row];
    return cell
}

答案 1 :(得分:0)

您可以清理不必要的实例:

-(void)prepareForReuse{
    [super prepareForReuse];
    [playerLayer removeFromSuperlayer];
    playerLayer = nil;
    playerItem = nil;
    asset = nil;
    player = nil;
}