ios - Memory Leak: AVplayerViewController -
i facing memory leaks when play video , return parent window. see screenshot below of readings allocations tool. every time, when pop view controller (showing video) there objects related avfoundation holding memory. interestingly responsible library of these objects avfoundation. none of increase in memory due objects created in app. highly unlikely there problem such popular framework. saw few examples of avplayerviewcontroller on web seem have same problem.
does have idea what/where problem? if wants replicate can download of 2 projects given above. have make minor changes in storyboard creating root view controller navigation controller.
- http://www.modejong.com/blog/post13_ios8_sunspot/index.html
https://github.com/coolioxlr/pageview-avplayer
this how clearing memory:
-(void) dealloc{ [self clearcurrentvideo]; } -(void)clearcurrentvideo { [_playeritem removeobserver:self forkeypath:@"status"]; [_currentvideoplayerviewcontroller.player removeobserver:self forkeypath:@"rate"]; [_currentvideoplayerviewcontroller.player pause]; _currentvideoplayerviewcontroller.delegate=nil; _currentvideoplayerviewcontroller.player=nil; _playeritem=nil; _currentvideoplayerviewcontroller = nil; }
this how load asset videos:
-(void)playtheasset:(avasset *)asset{ [asset loadvaluesasynchronouslyforkeys:@[@"playable"] completionhandler: ^{ dispatch_async( dispatch_get_main_queue(), ^{ [self loadtheasset:asset withkeys:@[@"playable"]]; }); }]; } - (void)loadtheasset:(avasset *)asset withkeys:(nsarray *)requestedkeys{ /* make sure value of each key has loaded successfully. */ (nsstring *thiskey in requestedkeys) { nserror *error = nil; avkeyvaluestatus keystatus = [asset statusofvalueforkey:thiskey error:&error]; if (keystatus == avkeyvaluestatusfailed) { //[self assetfailedtoprepareforplayback:error]; if([thiskey isequaltostring:@"playable"]){ [self shownetworkerrorlabel]; } return; } else if ((keystatus == avkeyvaluestatusloaded) || ( keystatus == avkeyvaluestatusloading )){ [self removenetworklabel ]; } } /* use avasset playable property detect whether asset can played. */ if (!asset.playable) { /* generate error describing failure. */ nsstring *localizeddescription = nslocalizedstring(@"item cannot played", @"item cannot played description"); nsstring *localizedfailurereason = nslocalizedstring(@"the assets tracks loaded, not made playable.", @"item cannot played failure reason"); nsdictionary *errordict = [nsdictionary dictionarywithobjectsandkeys: localizeddescription, nslocalizeddescriptionkey, localizedfailurereason, nslocalizedfailurereasonerrorkey, nil]; nserror *assetcannotbeplayederror = [nserror errorwithdomain:@"stitchedstreamplayer" code:0 userinfo:errordict]; nslog(@"%@",assetcannotbeplayederror); [self shownetworkerrorlabel]; /* display error user. */ [self assetfailedtoprepareforplayback:assetcannotbeplayederror]; return; } /* @ point we're ready set playback of asset. */ /* stop observing our prior avplayeritem, if have one. */ if (_playeritem) { /* remove existing player item key value observers , notifications. */ [_playeritem removeobserver:self forkeypath:@"status"]; [[nsnotificationcenter defaultcenter] removeobserver:self name:avplayeritemdidplaytoendtimenotification object:_playeritem]; [[nsnotificationcenter defaultcenter] removeobserver:self name:avplayeritemplaybackstallednotification object:_playeritem]; } /* create new instance of avplayeritem loaded avasset. */ _playeritem = [avplayeritem playeritemwithasset:asset]; /* observe player item "status" key determine when ready play. */ [_playeritem addobserver:self forkeypath:@"status" options:nskeyvalueobservingoptioninitial | nskeyvalueobservingoptionnew context:avplayerdemoplaybackviewcontrollerstatusobservationcontext]; /* when player item has played end time we'll toggle movie controller pause button play button */ [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(playeritemdidreachend:) name:avplayeritemdidplaytoendtimenotification object:_playeritem]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(playeritemfailedtoplaytoendtime:) name:avplayeritemplaybackstallednotification object:_playeritem]; // remove movie player view controller "playback did finish" notification observers // observe ourselves can use crossfade transition [[nsnotificationcenter defaultcenter] removeobserver:_currentvideoplayerviewcontroller name:kplayerviewdismissednotification object:_currentvideoplayerviewcontroller.player]; [[nsnotificationcenter defaultcenter] addobserver:self selector:@selector(videofinishedcallback:) name:kplayerviewdismissednotification object:_currentvideoplayerviewcontroller.player]; /* create new player, if don't have one. */ if (!_currentvideoplayerviewcontroller.player) { /* new avplayer initialized play specified player item. */ _currentvideoplayerviewcontroller.player=[avplayer playerwithplayeritem:self->_playeritem]; [_currentvideoplayerviewcontroller.player addobserver:self forkeypath:@"rate" options:nskeyvalueobservingoptionnew context:avplayerdemoplaybackviewcontrollerrateobservationcontext]; } }
i couldn't figure out reason behind this. tried using avplayer instead , created own ui using (reference apple avplayer demo app.) , couldn't find leak there. worked. if gets stuck similar problem give try reference code avplayer demo app. , if knows answer issue on thread. please let me know.
Comments
Post a Comment