ReloadData vs ReloadRowsAtIndexPaths(特别是关于来自文件的视频数据)

时间:2013-07-23 19:33:22

标签: ios objective-c cocoa-touch tableview

为什么将视频下载到文件路径需要[tableview reloadData]才能在tableview上看到?

我已经被困在这个问题上3天了,我感到非常困惑,而且devforums已经失败了。

基本上,我有一个tableview。每个表视图单元都有一个AVPlayer和一个给定的远程URL。在cellForRowAtIndexPath中,如果视频数据未在本地存储,则会将其下载并将其保存到文件中,并且AVPlayer会尝试在保存的文件位置播放视频。

问题是,什么都没有播放。

除非我在每个[tableView reloadData]中致电cellForRowAtIndexPath,否则视频会被渲染。我意识到这可能对性能非常不利,对用户来说也不是很好,所以我尝试对每个单元使用reloadRowsAtIndexPath,但这不起作用。

为什么我的应用需要调用reloadData才能从给定的本地文件位置加载数据?为什么reloadRowsAtIndexPath没有工作?在获取最近写入文件路径的视频数据方面,两者之间有什么区别。

我宁愿不重新加载任何东西,如果我没有重新加载tableview,那只是应用程序不知道给定文件路径中的新数据。


代码

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        static NSString *const cellIdentifier = @"cellIdentifier";
        AVideoTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
        AVURLAsset *asset = [AVURLAsset URLAssetWithURL:[self getURL:someURLString forIndexPath:indexPath] options:nil];
        AVPlayerItem *playerItem = [AVPlayerItem playerItemWithAsset:asset];
        if (!cell) {
            cell = [[AVideoTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
            cell.player = [[AVPlayer alloc] initWithPlayerItem:playerItem];
            AVPlayerLayer *layer = [AVPlayerLayer playerLayerWithPlayer:cell.player];
            cell.player.actionAtItemEnd = AVPlayerActionAtItemEndNone;
            layer.frame = CGRectMake(10.0, 10.0, 300.0, 179.0);
            [cell.layer addSublayer: layer];
        }
        else {
            [cell.player replaceCurrentItemWithPlayerItem:playerItem];
        }
        [cell.player play];

    }

2 个答案:

答案 0 :(得分:0)

所以你试图在每个表格单元格中播放视频?那不行。视频播放非常耗费资源。将视频图层添加到每个具有自己的播放器的表格视图单元格中是非启动性的。如果表格视图没有正确完成,那么表格视图对静止图像的表现很难。在表格单元格中实时显示视频几乎是不可能的。您需要重新考虑您的设计方法。也许只需加载表格单元格中每个视频的海报图像,然后在用户点击单元格时进行播放?

如果您坚持走这条路线以便自己可以看到,我的猜测是您可能没有使用正确的NSURL方法来实例化您的文件URL。在此行设置断点:

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:
                      [self getURL:someURLString forIndexPath:indexPath] 
                                        options:nil];

然后跳过该行,然后将鼠标悬停在资产变量上。如果它是零,那么您在getURL:forIndexPath:方法中实例化的NSURL出了问题。

确保您使用[NSURL fileURLWithPath:]从磁盘加载它。 iOS区分文件URL和Web URL。还要确保您的文件实际存在于您正在使用的文件URL中。

答案 1 :(得分:0)

我认为这是异步/同步问题。

我正在使用AFNetworking以getURL方法下载文件。

[operation waitUntilFinished]

^这解决了这个问题。我想,在getURL方法返回本地URL之前没有下载整个文件,因此资产可能已经损坏了。

唯一的问题是,我担心对于缓慢的互联网连接,主线程可能会被阻止太长时间。每个视频大约140KB。

如果你知道,一个不会阻止主线程的更好方法请告诉我。

很高兴在三个紧张的日子之后终于弄明白了。 :)