Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/38.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 UICollectionViewCell消息在退出队列后立即发送到解除分配的实例_Ios_Iphone_Swift_Swift2 - Fatal编程技术网

Ios UICollectionViewCell消息在退出队列后立即发送到解除分配的实例

Ios UICollectionViewCell消息在退出队列后立即发送到解除分配的实例,ios,iphone,swift,swift2,Ios,Iphone,Swift,Swift2,我有一个UICollectionViewCell,它正在排队等待重用。我最近引入了一个滑动抽屉功能,它基本上是一个隐藏视图,当用户滑动时会显示出来 在上次更改之后,这似乎创建了一个实例在初始化时被释放的情况。报告僵尸的确切位置是在调用“addGestureRecognizers()”时,从setupSlidingDrawer()调用“addGestureRecognizers()”,而setupSlidingDrawer()又从init函数调用 我附上了一张僵尸呼叫前后断点的图片。我整天都在看这

我有一个UICollectionViewCell,它正在排队等待重用。我最近引入了一个滑动抽屉功能,它基本上是一个隐藏视图,当用户滑动时会显示出来

在上次更改之后,这似乎创建了一个实例在初始化时被释放的情况。报告僵尸的确切位置是在调用“addGestureRecognizers()”时,从setupSlidingDrawer()调用“addGestureRecognizers()”,而setupSlidingDrawer()又从init函数调用

我附上了一张僵尸呼叫前后断点的图片。我整天都在看这个,一直在画空白

作为一种变通方法(hack),我将deleteView作为一个实例变量,这似乎可以防止类释放,因为保留计数没有减少

我觉得我的集合视图单元格/控制器的代码非常标准,我没有做任何疯狂的事情

这似乎是一个苹果的错误,但我似乎无法在互联网上找到任何东西来证明这一点。如果

class MomentsViewCell : UICollectionViewCell, UIGestureRecognizerDelegate {
    static let reuseIdentifier = "MomentsViewCell"
    let imageView = UIImageView()
    let activityIndicator = UIActivityIndicatorView()
    let shareButton = UIButton()  
    var shareCallback: (() -> ())?    
    var isSwiped = false
    let overlayViewTag = 999
    var delegate: MomentsViewController?

    let shareButtonLength: CGFloat = 44

    lazy var drawerWidth: CGFloat = {
        self.frame.width * 0.15
    }()

    override init(frame: CGRect) {
        super.init(frame: frame)
        contentView.addSubview(imageView)
        imageView.contentMode = UIViewContentMode.ScaleAspectFit
        imageView.snp_makeConstraints { (make) -> Void in
            make.centerX.equalTo(self.contentView.snp_centerX)
            make.width.equalTo(self.contentView.snp_width)
            make.top.equalTo(self.snp_top)
            make.bottom.equalTo(self.snp_bottom)
        }
        contentView.addSubview(activityIndicator)
        activityIndicator.hidesWhenStopped = true
        activityIndicator.snp_makeConstraints { (make) -> Void in
            make.center.equalTo(self.snp_center)
        }

        let shareImage = UIImage(named: "share-moment")
        shareButton.setImage(shareImage, forState: .Normal)
        shareButton.addTarget(self, action: "didTapShareButton", forControlEvents: .TouchUpInside)
        shareButton.enabled = false
        shareButton.alpha = 0.0
        imageView.addSubview(shareButton)
        imageView.userInteractionEnabled = true
        shareButton.snp_makeConstraints { (make) -> Void in
            let size = CGSizeMake(shareButtonLength, shareButtonLength)
            var offset = shareButtonLength / 2
            if let imageLength = shareImage?.size.height {
                offset = (shareButtonLength - imageLength) / 2
            }

            make.bottom.equalTo(self.imageView).multipliedBy(0.95).offset(offset)
            make.right.equalTo(self.imageView).multipliedBy(0.95).offset(offset)
            make.size.equalTo(size)
        }
        setupSlidingDrawer()
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func prepareForReuse() {
        super.prepareForReuse()
        imageView.image = nil

        exitDeleteMode()
    }

    func enableSharing() {
        shareButton.enabled = true
        shareButton.alpha = 1.0
    }

    func didTapShareButton() {
        shareCallback?()
    }

    func setupSlidingDrawer() {
        let deleteView = UIView(frame: CGRectMake(self.frame.width - drawerWidth, self.frame.origin.y, drawerWidth, self.frame.height))
        deleteView.backgroundColor = UIColor.whiteColor()
        let deleteGradientLayer = CAGradientLayer()
        deleteGradientLayer.frame = deleteView.bounds
        deleteGradientLayer.colors = [UIColor(hex: 0xE8557C).CGColor, UIColor(hex: 0xCC2B49).CGColor]
        deleteView.layer.insertSublayer(deleteGradientLayer, atIndex: 0)

        let trashButton = UIButton()
        trashButton.setImage(UIImage(named: "trash_can"), forState: UIControlState.Normal)
        trashButton.addTarget(self, action: Selector("didPressDelete"), forControlEvents: .TouchUpInside)
        deleteView.addSubview(trashButton)
        deleteView.bringSubviewToFront(trashButton)

        trashButton.snp_makeConstraints(closure: { (make) -> Void in
            make.center.equalTo(deleteView.snp_center)
            make.width.equalTo(deleteView.snp_width).multipliedBy(0.354)
            make.height.equalTo(deleteView.snp_height).multipliedBy(0.07)
        })
        contentView.addSubview(deleteView)

        deleteView.snp_makeConstraints(closure: { (make) -> Void in
            make.left.equalTo(self.imageView.snp_right)
            make.height.equalTo(self.contentView.snp_height)
            make.width.equalTo(drawerWidth)
        })
        addGestureRecognizers()
    }

    func addGestureRecognizers() {
        let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("didSwipeCell:"))
        swipeGestureRecognizer.delegate = self
        swipeGestureRecognizer.direction = .Left
        self.addGestureRecognizer(swipeGestureRecognizer)
    }


class MomentsViewController: ContainerSubController, UICollectionViewDelegate, UICollectionViewDataSource {
    var moments: [Moment] = []
    let layout = UICollectionViewFlowLayout()
    var collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: UICollectionViewFlowLayout())
    let headerIdentifier = "headerCellIdentifier"
    let headerLabelText = "Moments"
    let headerCellHeight: CGFloat = 103.0
    let noMomentsLabelText = "It's looking pretty empty in here! Assign a Moments action (Share Moment To Twitter) to a Hot Key to get started."
    let noMomentsReuseIdentifier = "NoMoments"
    var currentSwipedCellIndexPath: NSIndexPath?

    override func viewDidLoad() {
        super.viewDidLoad()

        layout.minimumLineSpacing = 0
        collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout)
        collectionView.showsVerticalScrollIndicator = false

        collectionView.backgroundColor = UIColor.clearColor()
        collectionView.registerClass(MomentsViewCell.self, forCellWithReuseIdentifier: MomentsViewCell.reuseIdentifier)
        collectionView.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: noMomentsReuseIdentifier)
        collectionView.registerClass(UICollectionViewCell.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: headerIdentifier)

        collectionView.delegate = self
        collectionView.dataSource = self
        view.backgroundColor = UIColor.blackColor()
        view.addSubview(collectionView)

        collectionView.snp_makeConstraints { (make) -> Void in
            make.height.equalTo(view)
            make.width.equalTo(view)
            make.center.equalTo(view)
        }
        setupTransitionToMainButton()
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        refreshMoments()
        collectionView.reloadData()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleMomentSavedNotifcation", name: MomentNotifcation.MomentSaved.rawValue, object: nil)

    }

    //MARK: UICollectionViewDataSource
    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

        guard let momentsViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(MomentsViewCell.reuseIdentifier, forIndexPath: indexPath) as? MomentsViewCell, moment = moments[safe:indexPath.row] else {
                return MomentsViewCell()
        }

在你的守卫中,确保返回你之前排队的
momentsViewCell

例如:

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

  if let momentsViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(MomentsViewCell.reuseIdentifier, forIndexPath: indexPath) as? MomentsViewCell {
   return momentsViewCell
  else {
   return MomentsViewCell()
   }
编辑


正如我看到的屏幕截图,日志是关于优化的警告。整个赋值可能不起作用,因为后来没有使用变量。

这是我们尝试的第一件事情之一,因为我们认为它们没有引用单元格,这就是导致其释放的原因,但它不起作用。当collectionView.dequeueReusableCellWithReuseIdentifier->init()时,将发生释放。因此,它是在变量初始化之前发布的。您能否详细说明(并在编辑问题时从问题中删除无用的图像)您到底做了什么以及结果是什么?此外,子视图不
也是很少见的。我不确定,现在是否可以,或者可能相关。我们移除了保护并直接使用:if let momentsViewCell=collectionView.dequeueReusableCellWithReuseIdentifier(momentsViewCell.reuseIdentifier,forIndexPath:indexPath)分配了矩单元作为?MomentsViewCell{对于弱子视图,我们没有使用outlet,因此不需要它们。尽管现在您在一个完全不相关的注释中提到了它,委托变量应该是弱的,