MPMoviePlayerController вызывает утечку

Я разрабатываю приложение iOS с очень тяжелым видео только для iPad, которое использует ARC, но похоже, что у меня есть утечка, когда я пытаюсь использовать MPMoviePlayerController, инструменты вызывают утечку памяти в строке кода, которая выделяет память для объекта видеоплеера, любые идеи ? Кроме того, кажется, что не происходит очистка видеоплеера после завершения воспроизведения видео.

Любая помощь будет очень признательна, я везде искал ответ на этот вопрос, поскольку вы можете сказать, что проблема в значительной степени ограничивает характер приложения.

код:

@interface ViewController ()
@property(nonatomic,strong) MPMoviePlayerController * vidPlayer;
@end

@implementation ViewController
@synthesize vidPlayer;

- (void)viewDidLoad
    {
        @autoreleasepool {

        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        [self playVideoForFile:@"01_intro"];
        }
    }

    -(void)playVideoForFile:(NSString*)p_fileName
    {    
            NSString *path = [[NSBundle mainBundle] pathForResource:p_fileName ofType:@"mp4"];
            NSURL *tempURI = [NSURL fileURLWithPath:path];
            vidPlayer = [[MPMoviePlayerController alloc] initWithContentURL:tempURI];

        [vidPlayer setControlStyle:MPMovieControlStyleNone];
        [vidPlayer setAllowsAirPlay:NO];

        [vidPlayer.view setFrame:CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.height,[[UIScreen mainScreen] bounds].size.width)];


        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(vidFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:vidPlayer];

        [vidPlayer play];

        [self.view addSubview:vidPlayer.view];

}

-(void)vidFinishedCallback:(NSNotification*)aNotification
{       
            [vidPlayer pause];
            vidPlayer.initialPlaybackTime = -1;
            [vidPlayer stop];
            vidPlayer.initialPlaybackTime = -1;
            [vidPlayer.view removeFromSuperview];
            vidPlayer = nil;

        [[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:vidPlayer];


}

person Michael James Lewis    schedule 16.04.2012    source источник
comment
Не могли бы вы опубликовать снимок экрана с результатом работы с инструментами?   -  person Squatch    schedule 16.04.2012


Ответы (3)


Я пытался

MPMoviePlayerController *movieController = [notification object];
[[NSNotificationCenter defaultCenter] removeObserver:self 
    name:MPMoviePlayerPlaybackDidFinishNotification 
    object:movieController];  
movieController = nil;

и это, кажется, работает.

person BabyPanda    schedule 06.07.2012

Это догадка, но попробуйте вызвать removeObserver до того, как vidPlayer будет уничтожен. В документации указано, что вы должны «Не забудьте вызвать removeObserver: или removeObserver: name: object: перед уведомлениемObserver или перед тем, как любой объект, указанный в addObserver: selector: name: object: будет освобожден». - NSNotification Center

Кроме того, вы можете попробовать удалить явный автоматический выпуск пула в viewDidLoad. В этом нет необходимости, если для каждого представления используется только один vidPlayer, и недавно были обнаружены некоторые проблемы с ARC и autoreleasepools. См. это исправление

person boxel    schedule 16.04.2012
comment
Спасибо за информацию об автовыпусках! и за то, что обнаружил эту школьную ошибку, но не удалось получить утечки ... welshkaratecollective.co.uk /screenshot_1.png welshkaratecollective.co.uk/screenshot_2.png - person Michael James Lewis; 16.04.2012

У меня была эта проблема, и она отправляла мне серый цвет! Каждый раз, когда создавался экземпляр нового видео, он никогда не выпускался (с использованием ARC) и по мере создания большего количества экземпляров viewController в конечном итоге приводил к неуклюжему сбою. Я тоже проверил все вызовы MPMoviePlayer, убедившись, что он остановлен и установлен в ноль.

Проблема заключалась не в выделении и выпуске MPMoviePlayerController, а в делегате, который использовался для передачи сведений о контроллере представления. В контроллере дочернего представления у меня был делегат для проверки переданных данных модели из tableViewController:

@property (strong, nonatomic) id<MyViewControllerDelegate> delegate;

Назначение сильного указателя вызвало огромную утечку памяти. Назначив его как «слабый», он устранил проблему.

@property (weak, nonatomic) id<MyViewControllerDelegate> delegate;

Как правило, делегатам контроллеров представлений назначают их как слабый указатель на свойство.

Удачи. Надеюсь, это устранит утечку!

person Dave Thwaites    schedule 30.05.2013