Ios AvPlayServiceController未立即解除分配
我正在TVos的应用程序中播放视频。我正在使用avplayervewcontroller播放视频。但当我按下苹果电视遥控器上的“菜单”按钮时,我会回到我来到这里的视图控制器,但视频仍在继续播放,8秒或10秒后,它就被释放了。这真的是一个很糟糕的错误,我被困在这几天。我们将非常感谢您的帮助 这是我的视图控制器代码Ios AvPlayServiceController未立即解除分配,ios,swift,avplayer,tvos,avplayerviewcontroller,Ios,Swift,Avplayer,Tvos,Avplayerviewcontroller,我正在TVos的应用程序中播放视频。我正在使用avplayervewcontroller播放视频。但当我按下苹果电视遥控器上的“菜单”按钮时,我会回到我来到这里的视图控制器,但视频仍在继续播放,8秒或10秒后,它就被释放了。这真的是一个很糟糕的错误,我被困在这几天。我们将非常感谢您的帮助 这是我的视图控制器代码 import Foundation import UIKit import AVKit class ViewController : UIViewController {
import Foundation
import UIKit
import AVKit
class ViewController : UIViewController {
var avplayerVC : AVPlayerViewController?
var recentlyWatchedTimer : NSTimer?
var lessonToWatch : Lesson?
override func viewDidLoad() {
super.viewDidLoad()
if let urlVideo = lessonToWatch?.lessonurl {
let activityIndicator = UIActivityIndicatorView(frame: CGRectMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0, 30.0, 30.0))
let asset : AVURLAsset = AVURLAsset(URL: NSURL.init(string: urlVideo)!, options: nil)
let keys = ["playable"];
avplayerVC = AVPlayerViewController()
weak var weakSelf = self
asset.loadValuesAsynchronouslyForKeys(keys) { () -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
weakSelf!.avplayerVC?.player = AVPlayer(playerItem: AVPlayerItem(asset: asset))
weakSelf!.avplayerVC?.player?.seekToTime(kCMTimeZero)
print("Status 1: " + "\(self.avplayerVC?.player?.status.rawValue)")
print(self.view?.frame)
// doesn't work
weakSelf!.avplayerVC?.view.frame = self.view.frame
activityIndicator.stopAnimating()
activityIndicator.removeFromSuperview()
weakSelf!.view.addSubview((self.avplayerVC?.view!)!)
weakSelf!.avplayerVC?.player?.play()
weakSelf!.recentlyWatchedTimer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: self, selector: "addToRecentlyWatched" , userInfo: nil, repeats: false)
})
}
print("In LessonPlayViewController View Did Load")
self.view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}
}
func addToRecentlyWatched() {
if let lesson = lessonToWatch {
DataManager.sharedInstance.addRecentlyWatch(lesson)
}
recentlyWatchedTimer?.invalidate()
}
deinit {
print("deinit")
avplayerVC?.view.removeFromSuperview()
avplayerVC?.player = nil
avplayerVC = nil
}
// MARK : AVPlayerViewControllerDelegate
}
您希望在异步回调块内的所有位置使用weakSelf,但同时打印self.view.frame。您希望在异步回调块内的所有位置使用weakSelf,但是您正在立即打印self.view.frame。您应该使用捕获列表来确保对
self
的所有引用在闭包中都是弱的。然后使用guard
检查引用在闭包内是否仍然有效
import Foundation
import UIKit
import AVKit
import AVFoundation
class ViewController : UIViewController {
var avplayerVC : AVPlayerViewController?
var recentlyWatchedTimer : NSTimer?
var lessonToWatch : Lesson?
override func viewDidLoad() {
super.viewDidLoad()
if let urlVideo = lessonToWatch?.lessonurl {
let activityIndicator = UIActivityIndicatorView(frame: CGRectMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0, 30.0, 30.0))
let asset : AVURLAsset = AVURLAsset(URL: NSURL.init(string: urlVideo)!, options: nil)
let keys = ["playable"];
avplayerVC = AVPlayerViewController()
asset.loadValuesAsynchronouslyForKeys(keys) { [weak self] in
dispatch_async(dispatch_get_main_queue()) { [weak self] in
guard let vc = self, playerVC = vc.avplayerVC else {
return
}
playerVC.player = AVPlayer(playerItem: AVPlayerItem(asset: asset))
playerVC.player?.seekToTime(kCMTimeZero)
print("Status 1: " + "\(playerVC.player?.status.rawValue)")
print(vc.view?.frame)
// doesn't work
playerVC.view.frame = vc.view.frame
activityIndicator.stopAnimating()
activityIndicator.removeFromSuperview()
vc.view.addSubview(playerVC.view)
playerVC.player?.play()
vc.recentlyWatchedTimer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: vc, selector: "addToRecentlyWatched" , userInfo: nil, repeats: false)
}
}
print("In LessonPlayViewController View Did Load")
self.view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}
}
func addToRecentlyWatched() {
if let lesson = lessonToWatch {
DataManager.sharedInstance.addRecentlyWatch(lesson)
}
recentlyWatchedTimer?.invalidate()
}
deinit {
print("deinit")
avplayerVC?.view.removeFromSuperview()
avplayerVC?.player = nil
avplayerVC = nil
}
// MARK : AVPlayerViewControllerDelegate
}
有关捕获列表的更多信息:
编辑
还请注意,在离开视图控制器时,应明确停止视频播放,而不是依赖播放机停止播放作为其释放的一部分。
例如,在视图中消失
或类似内容。您应该使用捕获列表来确保对self
的所有引用在闭包中都是弱的。然后使用guard
检查引用在闭包内是否仍然有效
import Foundation
import UIKit
import AVKit
import AVFoundation
class ViewController : UIViewController {
var avplayerVC : AVPlayerViewController?
var recentlyWatchedTimer : NSTimer?
var lessonToWatch : Lesson?
override func viewDidLoad() {
super.viewDidLoad()
if let urlVideo = lessonToWatch?.lessonurl {
let activityIndicator = UIActivityIndicatorView(frame: CGRectMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0, 30.0, 30.0))
let asset : AVURLAsset = AVURLAsset(URL: NSURL.init(string: urlVideo)!, options: nil)
let keys = ["playable"];
avplayerVC = AVPlayerViewController()
asset.loadValuesAsynchronouslyForKeys(keys) { [weak self] in
dispatch_async(dispatch_get_main_queue()) { [weak self] in
guard let vc = self, playerVC = vc.avplayerVC else {
return
}
playerVC.player = AVPlayer(playerItem: AVPlayerItem(asset: asset))
playerVC.player?.seekToTime(kCMTimeZero)
print("Status 1: " + "\(playerVC.player?.status.rawValue)")
print(vc.view?.frame)
// doesn't work
playerVC.view.frame = vc.view.frame
activityIndicator.stopAnimating()
activityIndicator.removeFromSuperview()
vc.view.addSubview(playerVC.view)
playerVC.player?.play()
vc.recentlyWatchedTimer = NSTimer.scheduledTimerWithTimeInterval(20.0, target: vc, selector: "addToRecentlyWatched" , userInfo: nil, repeats: false)
}
}
print("In LessonPlayViewController View Did Load")
self.view.addSubview(activityIndicator)
activityIndicator.startAnimating()
}
}
func addToRecentlyWatched() {
if let lesson = lessonToWatch {
DataManager.sharedInstance.addRecentlyWatch(lesson)
}
recentlyWatchedTimer?.invalidate()
}
deinit {
print("deinit")
avplayerVC?.view.removeFromSuperview()
avplayerVC?.player = nil
avplayerVC = nil
}
// MARK : AVPlayerViewControllerDelegate
}
有关捕获列表的更多信息:
编辑
还请注意,在离开视图控制器时,应明确停止视频播放,而不是依赖播放机停止播放作为其释放的一部分。
也就是说,在视图中消失了
或类似的情况。这没有任何区别。在异步内将所有self更改为weakSelfblock@Madu调用Denit时的堆栈跟踪是什么。这是哪根线?这没什么区别。在异步内将所有self更改为weakSelfblock@Madu调用Denit时的堆栈跟踪是什么。它是哪根线?