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
Swift drawRect抛出;致命错误:在展开可选值“时意外发现nil”;在Xcode操场_Swift_Swift Playground_Xcplayground - Fatal编程技术网

Swift drawRect抛出;致命错误:在展开可选值“时意外发现nil”;在Xcode操场

Swift drawRect抛出;致命错误:在展开可选值“时意外发现nil”;在Xcode操场,swift,swift-playground,xcplayground,Swift,Swift Playground,Xcplayground,为什么下面的代码抛出致命错误:在Xcode中运行时,在展开可选值时意外发现nil?我不确定下面的代码有什么问题。谢谢你的帮助。我还没试过在操场外跑步 import UIKit import XCPlayground class CircularProgressView: UIView { var progressBackgroundLayer: CAShapeLayer! var progressLayer: CAShapeLayer! var iconLayer: C

为什么下面的代码抛出
致命错误:在Xcode中运行时,在展开可选值时意外发现nil
?我不确定下面的代码有什么问题。谢谢你的帮助。我还没试过在操场外跑步

import UIKit
import XCPlayground

class CircularProgressView: UIView {
    var progressBackgroundLayer: CAShapeLayer!
    var progressLayer: CAShapeLayer!
    var iconLayer: CAShapeLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    convenience init() {
        self.init(frame: CGRectZero)
    }

    func setup() {
        progressBackgroundLayer = CAShapeLayer(layer: layer)
        progressLayer = CAShapeLayer(layer: layer)
        iconLayer = CAShapeLayer(layer: layer)
    }

    override func drawRect(rect: CGRect) {
        progressBackgroundLayer.frame = self.bounds
        progressLayer.frame = self.bounds
        iconLayer.frame = self.bounds
    }
}


var progressView = CircularProgressView(frame: CGRectMake(0, 0, 80, 80))

XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
XCPlaygroundPage.currentPage.liveView = progressView

您不应该使用
init(layer:)
初始化器来创建
CAShapeLayers
。(我的重点):

此初始值设定项用于创建层的卷影副本,例如,用于presentationLayer方法在任何其他情况下使用此方法将产生未定义的行为。例如,不要使用此方法使用现有层的内容初始化新层。

因此,由于在这种情况下调用此初始化器的行为是未定义的,因此在您的情况下,它将返回
nil
——然后在访问时强制展开,因为这是一个隐式展开的可选选项

您应该只使用
init()
创建层。我还建议您内联定义层实例,并去掉隐式展开的选项,如图所示。例如:

class CircularProgressView: UIView {
    let progressBackgroundLayer = CAShapeLayer()
    let progressLayer = CAShapeLayer()
    let iconLayer = CAShapeLayer()

...
func setup() {
    layer.addSublayer(progressBackgroundLayer)
    layer.addSublayer(progressLayer)
    layer.addSublayer(iconLayer)
}
为了将图层添加到视图中,需要使用视图图层上的方法。例如:

class CircularProgressView: UIView {
    let progressBackgroundLayer = CAShapeLayer()
    let progressLayer = CAShapeLayer()
    let iconLayer = CAShapeLayer()

...
func setup() {
    layer.addSublayer(progressBackgroundLayer)
    layer.addSublayer(progressLayer)
    layer.addSublayer(iconLayer)
}
另外,
drawRect:
用于绘制视图的内容,因此定义层的框架是完全错误的(仅当视图的边界更改时才会发生)。你应该考虑这样做。

最后,这段代码毫无意义:

convenience init() {
    self.init(frame: CGRectZero)
}

这正是
UIView
实现
init
所做的。

您不应该使用
init(layer:)
初始化器来创建
CAShapeLayers
。(我的重点):

此初始值设定项用于创建层的卷影副本,例如,用于presentationLayer方法在任何其他情况下使用此方法将产生未定义的行为。例如,不要使用此方法使用现有层的内容初始化新层。

因此,由于在这种情况下调用此初始化器的行为是未定义的,因此在您的情况下,它将返回
nil
——然后在访问时强制展开,因为这是一个隐式展开的可选选项

您应该只使用
init()
创建层。我还建议您内联定义层实例,并去掉隐式展开的选项,如图所示。例如:

class CircularProgressView: UIView {
    let progressBackgroundLayer = CAShapeLayer()
    let progressLayer = CAShapeLayer()
    let iconLayer = CAShapeLayer()

...
func setup() {
    layer.addSublayer(progressBackgroundLayer)
    layer.addSublayer(progressLayer)
    layer.addSublayer(iconLayer)
}
为了将图层添加到视图中,需要使用视图图层上的方法。例如:

class CircularProgressView: UIView {
    let progressBackgroundLayer = CAShapeLayer()
    let progressLayer = CAShapeLayer()
    let iconLayer = CAShapeLayer()

...
func setup() {
    layer.addSublayer(progressBackgroundLayer)
    layer.addSublayer(progressLayer)
    layer.addSublayer(iconLayer)
}
另外,
drawRect:
用于绘制视图的内容,因此定义层的框架是完全错误的(仅当视图的边界更改时才会发生)。你应该考虑这样做。

最后,这段代码毫无意义:

convenience init() {
    self.init(frame: CGRectZero)
}

这正是
UIView
实现
init
所做的。

setup()
layer
从何而来?这就是为什么您应该避免隐式展开选项。
layer
setup()中从何而来
?另外,这就是为什么您应该避免隐式展开选项。