Maison > Questions et réponses > le corps du texte
1.问题描述:
在ARC机制下,我需要做一个测试视频的软件。有用到3个方法,设置播放源方法A,在方法A中给创建的AVPlayerItem添加kvo方法B,在kvo方法B中判断视频状态,当数量达到并调用上报方法C,如未达到,则继续调用方法A。方法C上报结束后,继续调用方法A,如此循环。结果方法A中的player,playerItem,playerLayer,内存一直慢慢增大。
2.方法代码
方法A
-(void)CheckVideoURlCanPlay{
@autoreleasepool {
//发送检测视频播放可用性进度通知
NSDictionary *dict = @{@"type":@"checktraversalvideo",@"total":@(0),@"progress":@(self.needCheckArr.count)};
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"startcheckvideourl" object:nil userInfo:dict]];
@autoreleasepool {
if (self.needCheckArr == nil) {
self.needCheckArr = [VideoURLDataBase selectAllData];
}
if (self.needCheckArr.count == 0) {
isCheckOver = YES;
//NSLog(@"检查视频可播放性结束");
[self uploadVideoPlayResult:uploadArr isLast:1];
self.player = nil;
return;
}
if (_playItem != nil) {
[self.playItem removeObserver:self forKeyPath:@"status"];
self.playItem = nil;
self.player = nil;
[self.playLayer removeFromSuperlayer];
self.playLayer = nil;
}
VideoPlayDataObj *videoPlay = [self.needCheckArr objectAtIndex:0];
NSURL *url = [NSURL URLWithString:videoPlay.videoURL];
_player = [AVPlayer playerWithURL:url];
_playLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
_playLayer.videoGravity = AVLayerVideoGravityResizeAspect;
_playLayer.frame=CGRectMake(0, 80, 1, 1);
[self.view.layer addSublayer:self.playLayer];
[self.player play];
videoPlay = nil;
}
[_player.currentItem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionOld context:@"checkVideoCanPlay"];// 监听status属性
}
}
方法B
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
@autoreleasepool {
if ([keyPath isEqualToString:@"status"] && context == @"checkVideoCanPlay") {
AVPlayerItem *item = (AVPlayerItem *)object;
@autoreleasepool {
if ([item status] == AVPlayerStatusReadyToPlay) {
// NSLog(@"准备播放");
[self.player pause];
//VideoPlayDataObj *videoPlay = [VideoURLDataBase selectFirstData];
VideoPlayDataObj *videoPlay = [self.needCheckArr objectAtIndex:0];
if (videoPlay == nil) {//数据库中数据取完,则上传,然后跳出
[self uploadVideoPlayResult:uploadArr isLast:1];
return;
}
if (uploadArr == nil) {
uploadArr = [NSMutableArray array];
}
if (uploadArr.count<20){//上报结果数量
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[dict setObject:[defaults objectForKey:@"registerId"] forKey:@"agentid"];
[dict setObject:[NSString stringWithFormat:@"IOS %@", [[UIDevice currentDevice] systemVersion]] forKey:@"androidVersion"];
[dict setObject:@"" forKey:@"apkVersion"];
[dict setObject:@"0" forKey:@"buffertime"];
[dict setObject:@"4GIOS" forKey:@"categoryName"];
[dict setObject:@"120" forKey:@"categoryid"];
if(videoPlay.channelid == 0 ){
[dict setObject:@"0" forKey:@"channel"];
}else{
[dict setObject:videoPlay.channelid forKey:@"channel"];
}
[dict setObject:@"-40" forKey:@"dbm"];
[dict setObject:@"请求成功" forKey:@"description"];
[dict setObject:@"0" forKey:@"downspeed"];
[dict setObject:@"0" forKey:@"duration"];
[dict setObject:@"0" forKey:@"id"];
[dict setObject:@"0" forKey:@"islive"];
[dict setObject:isWifi forKey:@"nettype"];
[dict setObject:@"0" forKey:@"pchannel"];
[dict setObject:@"0" forKey:@"result"];
[dict setObject:@"0" forKey:@"resultCode"];
[dict setObject:[RequestUtils deviceVersion] forKey:@"terminal"];
[dict setObject:videoPlay.title forKey:@"testData"];
[dict setObject:[defaults objectForKey:@"username"] forKey:@"testMobile"];
[dict setObject:videoPlay.moviePath forKey:@"testModel"];
[dict setObject:[RequestUtils getTestTime] forKey:@"testTime"];
[dict setObject:@"6007" forKey:@"testfunid"];
[dict setObject:videoPlay.videoURL forKey:@"url"];
[uploadArr addObject:dict];
}else{
[self uploadVideoPlayResult:uploadArr isLast:0];
return;//跳出方法,等待上传完毕,发送通知,重新调用CheckVideoURlCanPlay
}
videoPlay = nil;
} else if ([item status] == AVPlayerStatusFailed) {
// NSLog(@"播放失败");
[self.player pause];
// VideoPlayDataObj *videoPlay = [VideoURLDataBase selectFirstData];
VideoPlayDataObj *videoPlay = [self.needCheckArr objectAtIndex:0];
[FailedURLDataBase insertIntoNewData:videoPlay.videoURL];
if (videoPlay == nil) {
[self uploadVideoPlayResult:uploadArr isLast:1];
return;
}
if (uploadArr ==nil) {
uploadArr = [NSMutableArray array];
}
if (uploadArr.count<20){
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[dict setObject:[defaults objectForKey:@"registerId"] forKey:@"agentid"];
[dict setObject:[NSString stringWithFormat:@"IOS %@", [[UIDevice currentDevice] systemVersion]] forKey:@"androidVersion"];
[dict setObject:@"" forKey:@"apkVersion"];
[dict setObject:@"0" forKey:@"buffertime"];
[dict setObject:@"4GIOS" forKey:@"categoryName"];
[dict setObject:@"120" forKey:@"categoryid"];
if(videoPlay.channelid ==0){
[dict setObject:@"0" forKey:@"channel"];
}else{
[dict setObject:videoPlay.channelid forKey:@"channel"];
}
[dict setObject:@"-40" forKey:@"dbm"];
[dict setObject:@"请求失败" forKey:@"description"];
[dict setObject:@"0" forKey:@"downspeed"];
[dict setObject:@"0" forKey:@"duration"];
[dict setObject:@"0" forKey:@"id"];
[dict setObject:@"0" forKey:@"islive"];
[dict setObject:isWifi forKey:@"nettype"];
[dict setObject:@"0" forKey:@"pchannel"];
[dict setObject:@"1" forKey:@"result"];
[dict setObject:@"0" forKey:@"resultCode"];
[dict setObject:[RequestUtils deviceVersion] forKey:@"terminal"];
[dict setObject:videoPlay.title forKey:@"testData"];
[dict setObject:[defaults objectForKey:@"username"] forKey:@"testMobile"];
[dict setObject:videoPlay.moviePath forKey:@"testModel"];
[dict setObject:[RequestUtils getTestTime] forKey:@"testTime"];
[dict setObject:@"6007" forKey:@"testfunid"];
[dict setObject:videoPlay.videoURL forKey:@"url"];
[uploadArr addObject:dict];
}else{
[self uploadVideoPlayResult:uploadArr isLast:0];
return;//跳出方法,等待上传完毕,发送通知,重新调用CheckVideoURlCanPlay
}
videoPlay = nil;
}
[NSThread sleepForTimeInterval:0.5];
[self.player.currentItem.asset cancelLoading];
[self.player.currentItem cancelPendingSeeks];
if (self.player.currentItem != nil) {
[self.player.currentItem removeObserver:self forKeyPath:@"status"];
_player = nil;
[_playLayer removeFromSuperlayer];
_playLayer = nil;
}
[self.needCheckArr removeObjectAtIndex:0];
[self CheckVideoURlCanPlay];
}//释放池括号
}
}
}
巴扎黑2017-04-18 09:06:24
En sortant, _player.currentItem removeObserver, puis vérifiez s'il y a une boucle dans le bloc
伊谢尔伦2017-04-18 09:06:24
L'objet n'a pas été publié. Ouvrons l'analyse de la mémoire et jetons un coup d'œil.
天蓬老师2017-04-18 09:06:24
[player.currentItem CancelPendingSeeks] ;
[player.currentItem.asset CancelLoading];
Ajoutez ces deux lignes de code pour libérer l'élément en cours de lecture