如果我设置了AVPlayerLayer,那么会有一些保留周期阻止deinit
被调用。
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")
}
}
使用此测试,只会打印" MyPlayer init" :
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
_ = MyPlayer()
return true
}
答案 0 :(得分:1)
在代码MyPlayer
中,请继续引用playerLayer
属性。 playerLayer
属性会引用MyPlayer
。这使得保留周期。
作为解决方案,您不需要在您的播放器类中存储playerLayer
属性。或者你可以创建一些装饰类,它们将管理玩家和他的图层
答案 1 :(得分:1)
AVPlayerLayer
保持对玩家的强烈引用,因此你不应该保持玩家本身对玩家层的强烈引用。
如果您不打算删除子图层,那么超级图层会为您保留参考,因此您可以使用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
}
如果您打算删除并重新添加子图层,那么您需要在UIView,UIViewController或其他管理器中为playerLayer创建强引用变量。