Getting error Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) when loading AVPlayer

和自甴很熟 提交于 2020-02-04 05:28:27

问题


I am trying to load an AVPlayer when I select a collectionViewCell, Here is my code in didSelectItem :

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if let item = items?[indexPath.item] {
        showPlayer(item: item)
    }
}

func showPlayer(item: Item) {

    let playerLauncher = PlayerLauncher()
    playerLauncher.showVideoPlayer()

    let playerView = PlayerView()
    playerView.item = item
    playerView.setupPlayerView()
}

This is my PlayerLauncher file:

class PlayerView: UIView {

    var item: Item? {
        didSet {
            if let id = item?.itemId {
               itemId = id
            } 
        }
    }

    var itemId = String()

    override init(frame: CGRect) {
        super.init(frame: frame)

        backgroundColor = UIColor(white: 0.3, alpha: 1)
    }

    var player: AVPlayer?

    func setupPlayerView() {

        let baseurl = "http://xample.com/play.m3u?id="

        let urlString = "\(baseurl)\(itemId)"
        print(urlString)
        if let url = URL(string: urlString) {
            player = AVPlayer(url: url)

            let playerLayer = AVPlayerLayer(player: player)
            self.layer.addSublayer(playerLayer)
            playerLayer.frame = self.frame

            let audioSession = AVAudioSession.sharedInstance()
            do{
                try audioSession.setCategory(AVAudioSessionCategoryPlayback)
            } catch let err {
                print(err)
                return
            }

            player?.play()

            player?.addObserver(self, forKeyPath: "currentItem.status", options: .new, context: nil)
        }
    }
}

class PlayerLauncher: NSObject {

    func showVideoPlayer() {
        print("Showing the player...")

        if let keyWindow = UIApplication.shared.keyWindow {
            let view = UIView(frame: keyWindow.frame)
            view.backgroundColor = UIColor.white

            view.frame = CGRect(x: keyWindow.frame.width - 10, y: keyWindow.frame.height - 10, width: 10, height: 10)

            let playerFrame = CGRect(x: 0, y: 0, width: keyWindow.frame.width, height: keyWindow.frame.height)
            let playerView = PlayerView(frame: playerFrame)
            view.addSubview(playerView)

            keyWindow.addSubview(view)

            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {
                view.frame = keyWindow.frame
            }, completion: { (completedAnimation) in
                //later...

            })
        }
    }
}

So whenever I select the item, the player starts loading, console prints the URL (because I've added print statement there), This is what it prints:

http://xample.com/play.m3u?id=12345
(lldb)

and then It crashes and shows Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT) error in AppDelegate. How can I fix it?

Thanks.

UPDATE:

I changed the didSelectItem func a bit. Here is the code:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

    if let item = items?[indexPath.item] {
        showPlayer(item: item)
    }
}

func showPlayer(item: Item) {
    let playerLauncher = PlayerLauncher()
    playerLauncher.showPlayer(item: item)
}

I changed the init method in PlayerView to this:

var item: Item? {
    didSet {
        if let id = item?.itemId {
            itemId = id
        }
    }
}

init(frame: CGRect, item: Item) {
    super.init(frame: frame)
    self.item = item

    setupPlayerView()
    setupContainerView()
    backgroundColor = UIColor(white: 0.3, alpha: 1)
}

And the required changes in PlayerLauncher:

let playerView = PlayerView(frame: playerFrame, item: item)
view.addSubview(playerView)

I put a break on let playerView line and I can see the item Id passed there. But it is not getting passed to the urlString in PlayerView class. Hence, ID is still " ".


回答1:


I've made a guide that hopefully shows what you've been misunderstanding.

I apologize to other readers for not using MARKDOWN text format, but please do consider this as my upmost attempt for the original poster. We've already went through sufficient discussions in the previous post.

So, how do you fix this? I guess there's nothing good to give you codes directly, please try to fix the code based on this information.

And if you have more questions, I'll try my best to help you :)




回答2:


It appears

class PlayerLauncher: NSObject

Has no way to reference

let playerView = PlayerView()

Try to define those outside the function scope so they can be changed by the function and referenced outside the function.



来源:https://stackoverflow.com/questions/46042139/getting-error-thread-1-exc-bad-access-code-exc-i386-gpflt-when-loading-avplay

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!