我正在尝试将 MPMoviePlayerController
添加到 View Controller ,但它在 play()
调用时被释放。该 URL 在打印时有效,我也在不同的 viewController
中使用了几乎相同的代码,并且它工作得很好。 View Controller 之间的唯一区别是这个 View Controller 是从不同的 viewController
中分离出来的。我一直在为此绞尽脑汁,并尝试了我可以在此处找到的所有类似解决方案,因此非常感谢任何帮助。
为 Segue 做准备
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "ShowChannel" {
if let destination = segue.destinationViewController as? ShowChannelController {
destination.channelId = channelId
destination.postsCollection = postsCollection
}
}
}
MPMoviePlayerController代码
var newMoviePlayer: MPMoviePlayerController!
var postsCollection = [Post]()
var videoPosition = 0
var channelId: String = ""
override func viewDidLoad() {
super.viewDidLoad()
startPlayingVideo(videoPosition)
updateNowPlaying(videoPosition)
}
func videoHasFinishedPlaying(notification: NSNotification) {
/* Find out what the reason was for the player to stop */
let reason =
notification.userInfo![MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]
as! NSNumber?
if let theReason = reason{
let reasonValue = MPMovieFinishReason(rawValue: theReason.integerValue)
stopPlayingVideo()
switch reasonValue!{
case .PlaybackEnded:
if (videoPosition < self.postsCollection.count - 1) {
videoPosition++
} else {
videoPosition = 0
}
startPlayingVideo(videoPosition)
let rowToSelect:NSIndexPath = NSIndexPath(forRow: videoPosition, inSection: 0);
self.tableView.selectRowAtIndexPath(rowToSelect, animated: true, scrollPosition: UITableViewScrollPosition.None);
updateNowPlaying(videoPosition)
case .PlaybackError:
/* An error happened and the movie ended */
print("Error happened")
case .UserExited:
/* The user exited the player */
print("User exited")
}
}
}
/** What to do when we stop playing a video */
func stopPlayingVideo() {
if let player = self.newMoviePlayer {
NSNotificationCenter.defaultCenter().removeObserver(self)
player.stop()
player.view.removeFromSuperview()
}
}
/** Initializes and starts the video player */
func startPlayingVideo(index: Int) {
let url: NSURL = NSURL(string: postsCollection[index].url)!
print(postsCollection[index].url)
self.newMoviePlayer = MPMoviePlayerController(contentURL: url)
if let player = self.newMoviePlayer {
NSNotificationCenter.defaultCenter().addObserver(self, selector: "videoHasFinishedPlaying:", name: MPMoviePlayerPlaybackDidFinishNotification, object: nil)
player.view.frame = CGRect(x: 0, y: ((self.view.bounds.size.height * 0.45) - (self.view.bounds.size.height / 3)), width: self.view.bounds.size.width, height: self.view.bounds.size.height / 3)
self.view.addSubview(player.view)
player.prepareToPlay()
player.play()
player.controlStyle = MPMovieControlStyle.Embedded
} else {
print("Failed to instantiate the movie player")
}
}
错误:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[OS_xpc_dictionary _postNotificationName:object:userInfo:]: unrecognized selector sent to instance 0x17ed2240'
启用僵尸:
-[MPMoviePlayerControllerNew _postNotificationName:object:userInfo:]: message sent to deallocated instance 0x17f47400**
最佳答案
终于意识到我的错误:
提到的第一个 ViewController 具有类似的实现,并且工作正常,但没有正确处理“NotificationCenter”,两个独立类中的观察者感到困惑。
解决方案:
在第一个 ViewController
的 viewDidDisappear()
中移除观察者
FirstViewController.swift
override func viewDidDisappear(animated: Bool) {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
经验教训:不要忘记注销自己!
关于ios - MPMoviePlayerController 在 play() 时被释放 - swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31545366/