Swift iOS: Memory leaks with the following code (v

2019-09-05 01:25发布

问题:

I play a full screen video with a perpetual loop in my game (for the background). It works well but when I change the view, I get memory leaks identified with Instruments (Memory leaks template) on this code:

urlStr = NSBundle.mainBundle().pathForResource("Video_Socle", ofType: "mov")
    let url = NSURL(fileURLWithPath: urlStr!)

    player = AVPlayer(URL: url)

    NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
    { notification in
        let t1 = CMTimeMake(5, 100);
        self.player!.seekToTime(t1)
        self.player!.play()

    }

    videoNode = SKVideoNode(AVPlayer: player!)
    videoNode!.anchorPoint = CGPointMake (0,0)
    videoNode!.size = CGSize(width: 2048, height: 1536)
    videoNode!.zPosition = 0


    background.addChild(videoNode!)
    if synch == false { video_synchronization()
    }
    videoNode!.play()

I have created a small cleaning function called when I change my view with the following code:

NSNotificationCenter.defaultCenter().removeObserver(self)
player = nil
videoNode = nil

background.removeAllActions()
background.removeAllChildren()

let transition = SKTransition.revealWithDirection(.Right, duration: 2)
        let nextScene = MainView(size: scene!.size)
        nextScene.scaleMode = .AspectFill
        scene?.view?.presentScene(nextScene, transition: transition)

        self.viewController?.dismissViewControllerAnimated(true, completion: nil)

I get memory leaks identified on the AVPlayer and SKVideoNode. Something strange is the leaks disapear when I remove the part:

NSNotificationCenter.defaultCenter().addObserverForName(AVPlayerItemDidPlayToEndTimeNotification, object: player!.currentItem, queue: nil)
{ notification in
    let t1 = CMTimeMake(5, 100);
    self.player!.seekToTime(t1)
    self.player!.play()
}

What am I missing with this code ? Thanks !

回答1:

when you are changing the view you need to do the following..

If you have any view on which you are playing video .. You need to remove it.

view.removeFromSuperView()



回答2:

The real problem in your code in observer which has strong reference of your object. you have used

self.player!.seekToTime(t1)
self.player!.play()

self is a strong reference and you should use [weak self]. This will work well