Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/120.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios Swift:删除collectionViewCell中的playerLayer';s preparefore崩溃_Ios_Swift - Fatal编程技术网

Ios Swift:删除collectionViewCell中的playerLayer';s preparefore崩溃

Ios Swift:删除collectionViewCell中的playerLayer';s preparefore崩溃,ios,swift,Ios,Swift,我试图删除avPlayerLayer以避免潜在的内存问题,但它崩溃了 我有一个显示TweetCell的主集合视图控制器,在每个TweetCell中,我有一个mediaCollectionView显示水平滚动的MediaCells。如果要显示的内容是视频,则每个mediaCell都将包含一个avPlayer 正如我从多篇SO帖子中了解到的,删除avPlayerLayer是正确的做法,因此我在prepareforeuse中实现了它 以下是我的实现: //At TweetCell class Twee

我试图删除avPlayerLayer以避免潜在的内存问题,但它崩溃了

我有一个显示
TweetCell
的主集合视图控制器,在每个
TweetCell
中,我有一个
mediaCollectionView
显示水平滚动的
MediaCells
。如果要显示的内容是视频,则每个mediaCell都将包含一个avPlayer

正如我从多篇SO帖子中了解到的,删除avPlayerLayer是正确的做法,因此我在
prepareforeuse
中实现了它

以下是我的实现:

//At TweetCell
class TweetCell: UICollectionViewCell {

    lazy var mediaCollectionView: UICollectionView = {
        let size = NSCollectionLayoutSize(
            widthDimension: NSCollectionLayoutDimension.fractionalWidth(1),
            heightDimension: NSCollectionLayoutDimension.fractionalHeight(1)
        )
        
        let item = NSCollectionLayoutItem(layoutSize: size)
        let group = NSCollectionLayoutGroup.horizontal(layoutSize: size, subitem: item, count: 1)
        let section = NSCollectionLayoutSection(group: group)
        section.orthogonalScrollingBehavior = .paging
        
        let layout = UICollectionViewCompositionalLayout(section: section)
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .systemGray
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.dataSource = self
        cv.delegate = self
        cv.register(MediaCell.self, forCellWithReuseIdentifier: "cell")
        return cv
    }()

    
    var tweet: Tweet? {
        didSet {
            if let tweet = tweet {
                //Setup other UI elements...
                
                //Refresh mediaCollectionView
                mediaCollectionView.reloadData()
                mediaCollectionView.scrollToItem(at: IndexPath(item: 0, section: 0), at: .top, animated: false)
                
            }
        }
    } 

    override func prepareForReuse() {
        
        tweet = nil
        //Other UI elements reset, eg, profileImageView.image = nil, or tweetLabel.text = ""

        super.prepareForReuse()
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MediaCell
        
        if tweet?.photosArray != nil {
            cell.media = tweet?.photosArray?[indexPath.item]

        } else if let videos = tweet?.videosArray {
            cell.media = videos[indexPath.item]
        } 
        return cell
    }

//At MediaCell
class MediaCell: UICollectionViewCell {
    
    let imageView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.contentMode = .scaleAspectFill
        iv.clipsToBounds = true
        iv.backgroundColor = .systemGreen
        return iv
    }()
    
    var videoView: AVPlayerView = {
        let v = AVPlayerView()
        v.translatesAutoresizingMaskIntoConstraints = false
        v.isHidden = false
        v.backgroundColor = .systemBlue
        return v
    }()
    
    var player : AVPlayer?
    var playerLayer: AVPlayerLayer? //Not in use
    
    var media: [String: AnyObject]? {
        didSet {
            guard let media = media else {return}

            if mediaType == "photo" {
                //PHOTOS
                
                ///Toggle image/video view
                removeAndDeactivateSubview(view: videoView)
                addAndActivateSubview(view: imageView)
        
                let url = URL(string: media["media_url_https"] as? String ?? "")
                imageView.sd_setImage(with: url)
                
            } else if mediaType == "video" {
                //VIDEOS
                
                ///Toggle image/video view
                removeAndDeactivateSubview(view: imageView)
                addAndActivateSubview(view: videoView)
                
                guard let urlString = media["url"] as? String else {return}
                guard let url = URL(string: urlString) else {return}
                
                player = AVPlayer(url: url)
                player?.isMuted = true
                let castedLayer = videoView.layer as? AVPlayerLayer
                castedLayer?.player = player
                
            } else {
                print("Some other media content type")
            }
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    func addAndActivateSubview(view: UIView) {
        addSubview(view)
        activateSubview(view: view)
    }
    
    func removeAndDeactivateSubview(view: UIView) {
        deactivateSubview(view: view)
        view.removeFromSuperview()
    }
    
    func activateSubview(view: UIView) {
        view.topAnchor.constraint(equalTo: topAnchor).isActive = true
        view.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
        view.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
    }
    
    func deactivateSubview(view: UIView) {
        view.topAnchor.constraint(equalTo: topAnchor).isActive = false
        view.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = false
        view.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = false
        view.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = false
    }
    
    override func prepareForReuse() {
        imageView.image = nil
        player = nil
        
        //CRASH HERE
        if let layer = videoView.layer as? AVPlayerLayer {
            layer.player = nil
            layer.removeFromSuperlayer()
        }

        super.prepareForReuse()
    }

//Custome AVPlayerView
class AVPlayerView: UIView {
    override class var layerClass: AnyClass {
        return AVPlayerLayer.self
    }
}
如果let layer=videoView.layer as,则崩溃消息指向
中的
.layer
对象?AVPlayerLayer
带有以下消息:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x47cd649dd8e0)

我已尝试在
super.prepareforeuse
之后删除avPlayerLayer,但它也会崩溃。

是否尝试将此代码放在tableViewDelegate->DiEndDisplatingCell中?这可能是一个好消息difference@ArikSegal是的,我试过这样做。我将它放在HomeController的DiEndDisplay中,它在
TweetCell
中的
super.prepareForReuse()
崩溃。您是否尝试将此代码放在tableViewDelegate->DiEndDisplatingCell中?这可能是一个好消息difference@ArikSegal是的,我试过这样做。我把它放在HomeController的DiEndDisplay中,它在
TweetCell
中的
super.prepareForReuse()
崩溃了。