Sti*_*Sti 40 multithreading cocoa-touch objective-c ios avplayer
我有一个UITableView包含滚动时要播放的视频.由于tableView中的单元格正在被重用,我只会AVPlayer为每一行实例化一个.当一个单元被重用时,我只需PlayerItem通过调用来改变单元的播放器[self.player replaceCurrentItemWithPlayerItem:newItem];.目前这是内部间接调用的tableView:cellForRowAtIndexPath.向下滚动时,重新使用时会出现明显的延迟.通过消除过程,我得出结论,滞后是replaceCurrentItemWithPlayerItem在它开始播放之前引起的.当删除这一行代码(阻止播放器获取新视频)时,滞后消失.
我试图解决它:
我有一个UITableViewCell播放这些视频的自定义,我在这些视频中创建了一个方法,用来自对象的新信息进行初始化.IE,在cellForRowAtIndexPath:我打电话[cell initializeNewObject:newObject];中执行以下方法:
//In CustomCell.m
-(void)initializeNewObject:(CustomObject*)newObject
{ /*...*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
AVPlayerItem *xPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:newObject.url]];
AVPlayer *dummy = self.player;
[dummy replaceCurrentItemWithPlayerItem:xPlayerItem];
dispatch_async(dispatch_get_main_queue(), ^{
self.player = dummy;
playerItem = xPlayerItem;
}
}/*...*/
}
Run Code Online (Sandbox Code Playgroud)
运行此操作时,我得到的结果与完全删除更换项目的调用相同.显然,这个函数不能被线程化.我不完全确定我对此的期望.我会想象我需要一个干净copy的AVPlayer这个工作,但搜索了一下后,我发现了一些意见指出,replaceCurrentItemWithPlayerItem:可不能在一个单独的线程,这是没有意义的我被调用.我知道UI元素永远不应该在除main/UI-thread之外的其他线程中处理,但我绝不会想到replaceCurrentItemWithPlayerItem属于这个类别.
我现在正在寻找一种方法来改变一个AVPlayer没有滞后的项目,但找不到任何.我希望我已经理解了这个函数的错误,并且有人会纠正我.
编辑:
我现在已被告知此调用已经线程化,这不应该发生.但是,我没有看到其他解释..下面是我的cellForRowAtIndexPath:.它位于自定义内UITableView,委托设置为self(so self == tableView)
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = [self dequeueReusableCellWithIdentifier:kCellIdentifier];
if(!cell)
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil] objectAtIndex:0];
//Array 'data' contains all objects to be shown. The objects each have titles, url's etc.
CustomVideoObject *currentObject = [data objectAtIndex:indexPath.row];
//When a cell later starts playing, I store a pointer to the cell in this tableView named 'playing'
//After a quick scroll, the dequeueing cell might be the cell currently playing - resetting
if(playing == cell)
playing = nil;
//This call will insert the correct URL, title, etc for the new video, in the custom cell
[cell initializeNewObject:currentObject];
return cell;
}
Run Code Online (Sandbox Code Playgroud)
在initializeNewObject当前正在"工作",但滞后(这里面CustomCell.m:
-(void)initializeNewObject:(CustomObject*)o
{
//If this cell is being dequeued/re-used, its player might still be playing the old file
[self.player pause];
self.currentObject = o;
/*
//Setting text-variables for title etc. Removed from this post, but by commenting them out in the code, nothing improves.
*/
//Replace the old playerItem in the cell's player
NSURL *url = [NSURL URLWithString:self.currentObject.url];
AVAsset *newAsset = [AVAsset assetWithURL:url];
AVPlayerItem *newItem = [AVPlayerItem playerItemWithAsset:newAsset];
[self.player replaceCurrentItemWithPlayerItem:newItem];
//The last line above, replaceCurrentItemWithPlayerItem:, is the 'bad guy'.
//When commenting that one out, all lag is gone (of course, no videos will be playing either)
//The lag still occurs even if I never call [self.player play], which leads me
//to believe that nothing after this function can cause the lag
self.isPlaying = NO;
}
Run Code Online (Sandbox Code Playgroud)
每次都在完全相同的地方发生滞后.当快速向下滚动时,我们可以看到当最底部单元格的顶部到达屏幕中心时发生短暂滞后.我想这对你没有任何意义,但很明显,每次都在完全相同的地方发生滞后,即当一个新的细胞出列时.更改了playerItem之后AVPlayer,我什么都不做.直到稍后我才开始播放视频.replaceCurrentItemWithPlayerItem: 是造成这种明显的滞后.文档声明它正在更改另一个线程中的项目,但该方法中的某些内容正在阻止我的UI.
我被告知要在仪器中使用Time Profiler来查明它是什么,但我不知道该怎么做.通过运行探查器并偶尔滚动一次,这就是结果(图像).每个图组的峰值都是我所说的滞后.当我滚动到底部并点击状态栏滚动到顶部时,单个极端峰值(我认为).我不知道如何解释结果.我搜索了堆栈replace,找到了这个混蛋.它从内部Main Thread(在顶部)调用,这是有意义的,50ms的"运行时间",我不知道这一点.图的相关比例是约1分半的时间跨度.相比之下,当评论该单行并再次运行Time Profiler时,图形的峰值显着降低(最高峰值为13%,与图像上的峰值相比,可能约为60-70%).
我不知道该找什么..
| 归档时间: |
|
| 查看次数: |
5310 次 |
| 最近记录: |