Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/103.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.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 为什么我们需要由dequeueReusableCell func获得的向上转换单元?_Ios_Swift_Uicollectionview - Fatal编程技术网

Ios 为什么我们需要由dequeueReusableCell func获得的向上转换单元?

Ios 为什么我们需要由dequeueReusableCell func获得的向上转换单元?,ios,swift,uicollectionview,Ios,Swift,Uicollectionview,事实上,我很困惑 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MessageCell

事实上,我很困惑

 override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MessageCell
    if let message = messages?[indexPath.item] {
        cell.message = message
    }
    cell.timeLibel
    return cell
}
我应该将单元格向上转换为reuseIdentifier暗示的类。因此,事实证明(在我的例子中),DequeReusablecell函数的结果不是MessageCell类,即使我已经准确地注册了它

 collectionView?.register(MessageCell.self, forCellWithReuseIdentifier: cellId)
此外,当我试图看到它是真实的而不是MessageCell实例时

cell.isKind(of: MessageCell.self)
这是真的。但同时,当我试图访问MessageCell类的实例属性时,它抛出一个错误“类型为'UICollectionViewCell'的值没有成员'message”

但参考称:

将委托方法中的相应视图出列后, 配置其内容并将其返回到集合视图以供使用

从UICollectionViewDataSource的引用:

此方法的实现负责创建, 配置并返回给定项的相应单元格。 你可以通过打电话给 集合的dequeueReuseAbleCell(withReuseIdentifier:for:)方法 查看并传递与单元对应的重用标识符 你想要的类型

为什么我们需要向上投射 let cell=collectionView.dequeueReusableCell(withReuseIdentifier:cellId,for:indexPath)

这是MessageCell等

 class MessageCell: BaseCell {
var message: Message? {
    didSet {
        nameLabel.text = message?.friend?.name
        if let profileImageName = message?.friend?.profileImageName {
            profileImageView.image = UIImage(named: profileImageName)
            messageLabel.text = message?.text
        }
    }
}
let profileImageView: UIImageView = {
    let imageView = UIImageView()
    imageView.contentMode = .scaleAspectFill
    imageView.layer.cornerRadius = 34
    imageView.layer.masksToBounds = true

    return imageView
}()

let dividerLineView: UIView = {
    let view = UIView()
    view.backgroundColor = UIColor(white: 0.5, alpha: 0.5)
    return view
}()
    let nameLabel: UILabel = {
    let label = UILabel()
    label.text = "Mark Zuckerberg"
    label.font = UIFont.systemFont(ofSize: 18)
//    label.backgroundColor = UIColor.brown
    return label
}()

let messageLabel: UILabel = {
    let label = UILabel()
    label.text = "Your friends message and something else..."
    label.textColor = UIColor.darkGray
    label.font = UIFont.systemFont(ofSize: 14)
//    label.backgroundColor = UIColor.green
    return label
}()


let timelabel : UILabel = {
    let label = UILabel()
    label.text = "12:05 pm"
    label.font = UIFont.systemFont(ofSize: 16)
    label.textAlignment = .right
//    label.textColor = UIColor.white
//    label.backgroundColor = UIColor.black
    return label

}()

let hasReadImageView: UIImageView = {
    let imageView = UIImageView()
   imageView.contentMode = .scaleAspectFill
    imageView.layer.cornerRadius = 10
    imageView.layer.masksToBounds = true

    return imageView
}()
override func setupViews() {

    addSubview(profileImageView)
     addSubview(dividerLineView)
    profileImageView.image = UIImage(named: "zuckprofile")
    hasReadImageView.image = UIImage(named: "zuckprofile")
    setupContainerView()

    addConstraintsWithFormat( "H:|-12-[v0(68)]|", views: profileImageView)
    addConstraintsWithFormat( "V:[v0(68)]", views: profileImageView)
    addConstraint(NSLayoutConstraint(item: profileImageView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    addConstraintsWithFormat( "H:|-82-[v0]|", views: dividerLineView)
    addConstraintsWithFormat( "V:[v0(1)]|", views: dividerLineView)



}
func setupContainerView() {
    let containerView = UIView()
     addSubview(containerView)

    addConstraintsWithFormat("H:|-90-[v0]|", views: containerView)
    addConstraintsWithFormat(  "V:[v0(50)]", views: containerView)
    addConstraint(NSLayoutConstraint(item: containerView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0))
    containerView.addSubview(nameLabel)
    containerView.addSubview(messageLabel)
    containerView.addSubview(timelabel)
    containerView.addSubview(hasReadImageView)
    containerView.addConstraintsWithFormat( "H:|[v0][v1(80)]-12-|", views: nameLabel, timelabel )
    containerView.addConstraintsWithFormat( "V:|[v0(26)][v1(24)]|", views: nameLabel,messageLabel )
    containerView.addConstraintsWithFormat( "H:|[v0]-8-[v1(20)]-12-|", views: messageLabel, hasReadImageView )
    containerView.addConstraintsWithFormat("V:[v0(20)]|", views: hasReadImageView)
    containerView.addConstraintsWithFormat( "V:|[v0(24)]", views: timelabel)
   addConstraint(NSLayoutConstraint(item: nameLabel, attribute: .centerY, relatedBy: .equal, toItem: timelabel, attribute: .centerY, multiplier: 1, constant: -1.4 ))


}

}



 extension UIView {
func addConstraintsWithFormat(_ format: String , views: UIView...) {
    var viewsDictionary = [String: UIView]()
    for (index, view) in views.enumerated() {
        let key = "v\(index)"
        viewsDictionary[key] = view
        view.translatesAutoresizingMaskIntoConstraints = false
    }
    addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
}
}



 class BaseCell : UICollectionViewCell {
let a = 5
override init(frame: CGRect) {
    super.init(frame: frame)
    setupViews()
    layer.masksToBounds = true
}
required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}

func setupViews() {
    backgroundColor = UIColor.blue

}
 }

为了提高内存效率,可以使用dequeueReusable。它在较低级别的工作方式我的朋友对此有详细的解释


我希望它能回答您的问题。

如果我没记错的话,isKindOf将检查对象是否可以成功铸造为该类型。但实际上并不是这样。您需要自己完成这项工作,因为只有您知道您已为该ReuseIdentifier注册的类型。请重新查看我的问题种类(of:)返回一个布尔值,该值指示接收方是给定类的实例还是从该类继承的任何类的实例。MessageCell看起来像什么?这是生成时和运行时发生的情况之间的差异。dequeue函数的定义表示它返回一个UICollectionView单元格,这意味着它也可以是MessageCell所在的子类。因此,在构建时,编译器不知道将返回什么(没有进行编译来确定这一点),因此必须向下转换到正确的类型。但是,在运行时,系统确切地知道它是什么,因此可以确定正确的类型。