在 SWIFT 中向下投射

DOWNCASTING IN SWIFT

提问人:EinStyn 提问时间:8/14/2023 更新时间:8/14/2023 访问量:99

问:

我在使用 Swift 时遇到问题。我有一个班级:

class ClassA : UIView{

    override public init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    init(from uiview: UIView) {
        super.init(frame: .zero)
    }

}

然后我有另一个类PageViewer

class PageViewer: UIView{

    var values : [ClassA]?
    var location: Int = 0

    public func test(){
        for i in 0..<values!.count {
            location = i
            values![i] = self.subviews[location] as! ClassA
        }
    }
}

问题: 我正在尝试将 UIViews 作为子视图添加到页面查看器,但我在这一行上收到一个运行时异常,说我想知道是否有可能的解决方法。values![i] = self.subviews[location] as! ClassACould not cast value of type 'UIView' to 'MyTestApp.ClassA.

iOS Swift UIView UIKit 已投稿

评论

1赞 luk2302 8/14/2023
所有子视图都是实例吗?ClassA
1赞 Shehata Gamal 8/14/2023
确保 的所有子视图的类型PageViewerClassA
1赞 Paulw11 8/14/2023
可能还有其他子视图不是 的实例。每次使用!要强制下行或强制展开,则有崩溃的风险。另外,如果您有子视图中的更多元素怎么办?您将遇到数组边界崩溃。你说你正在尝试添加子视图,但这段代码没有这样做。它正在访问子视图。更好的方法是迭代,并在获得 的实例时将其附加到数组中。PageViewerClassAvaluesself.subviewsClassA
1赞 Shehata Gamal 8/14/2023
不,强制转换不起作用,您当前的子类与您添加到寻呼机的子视图之间没有关系ClassA
1赞 luk2302 8/14/2023
如果我给你任何水果,你能假设它是苹果吗,因为苹果是水果?显然不是。

答:

1赞 cutiko 8/14/2023 #1

你总是可以向下投掷,但有时只能向上投掷。在这种情况下,您说所有子视图都可以是任何东西;强制它们成为特定的视图类型,以便我们可以将它们锤入此数组中。根据你要做的事情,必须有一种更优雅的方式来做到这一点,但如果你真的需要一个解决方法,那么:

self.subviews[location].forEach { subView in
    if subView is ClassA {
        values.append(subView as! ClassA)
    }
}

这应该通过,因为正在验证子视图实际上是“CVla”

评论

2赞 Rob Napier 8/14/2023
我相信你已经扭转了上行和下行。向上投射是超类型,并且总是可能的。我认为你的意思是.没有必要在这里尴尬或。values = subviews.compactMap { $0 as? ClassA }forEachas!
0赞 EinStyn 8/14/2023
感谢我的子视图最初不是 ClassA 的实例,您的代码帮助我注意到了这一点。
0赞 cutiko 8/15/2023
@RobNapier是的!你是对的,我这样说是因为对于没有经验的开发人员来说,super 更容易理解为“down”,因为任何实现都超过了 super 的最小值,所以 super all 认为是继承树中的分层父级,它的功能比任何实现都少。嘿! TIL TY.compactMap