If I ever set an AVPlayerLayer, then there will be some retain cycle that will prevent deinit
from ever being called.
import AVFoundation
class MyPlayer: AVPlayer {
fileprivate(set) lazy var playerLayer: AVPlayerLayer = {
// Create a player layer
$0.videoGravity = AVLayerVideoGravityResizeAspectFill
$0.backgroundColor = UIColor.black.cgColor
return $0
}(AVPlayerLayer(player: self))
override init() {
super.init()
print("MyPlayer init")
_ = playerLayer
}
deinit {
print("MyPlayer deinit")
}
}
Testing with this, only "MyPlayer init" will be printed:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
_ = MyPlayer()
return true
}
AVPlayerLayer
is keeping a strong reference to the player, so you shouldn't keep a strong reference of the playerLayer from the player itself.
If you don't plan to remove the sublayer, then the superlayer will keep the reference for you, so you can use weak
:
private weak var _playerLayer: AVPlayerLayer?
var playerLayer: AVPlayerLayer! {
if let p = _playerLayer {
return p
}
let p: AVPlayerLayer = {
// Create a player layer
$0.videoGravity = AVLayerVideoGravityResizeAspectFill
$0.backgroundColor = UIColor.black.cgColor
return $0
}(AVPlayerLayer(player: self))
_playerLayer = p
return p
}
If you plan to remove and re-add the sublayer, then you need the strong reference variable to be made in your UIView, UIViewController or some other manager for the playerLayer.