swift class 属性 行为

swift class property behavior

感谢您帮助我们弄清楚 class 中的 属性 会发生什么。

class CustomCorner: MDCCornerTreatment{
    var radius: CGFloat = 12;

    convenience init(radius: CGFloat) {
        self.init();
        self.radius = radius;
        print("Corner initialized with radius=\(self.radius)");
    }

    override func pathGeneratorForCorner(withAngle angle: CGFloat) -> MDCPathGenerator {
        print("entering pathGeneratorForCorner with radius \(self.radius)")
        
        let path = MDCPathGenerator(start: CGPoint(x: 0, y: radius))
        print("continuing pathGeneratorForCorner with radius \(radius)")
        path.addLine(to: CGPoint(x: radius, y: radius))
        path.addLine(to: CGPoint(x: radius, y: 0))
        return path
    }
}

与此代码一起使用时:

    let mdcRectangleShape = MDCRectangleShapeGenerator()
    let customCorner = CustomCorner(radius: 8)
    
    print("step 1 radio=\(customCorner.radius)")
    customCorner.radius = 5
    
    print("step 2 radio=\(customCorner.radius)")
    mdcRectangleShape.setCorners(customCorner)
    
    print("step 3 radio=\(customCorner.radius)")
    let _ = customCorner.pathGeneratorForCorner(withAngle: 10)
    nextButton.shapeGenerator = mdcRectangleShape
    
    print("step 4 radio=\(customCorner.radius)")

我得到以下输出:

Corner initialized with radius=8.0
step 1 radio=8.0
step 2 radio=5.0
step 3 radio=5.0
entering pathGeneratorForCorner with radius 5.0
continuing pathGeneratorForCorner with radius 5.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
step 4 radio=5.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0

这里我使用 Material 设计组件 iOS,尽管问题看起来更像是 Swift 问题。
这是我的调试代码,我故意插入不同的值来显示问题。
无论我如何设置半径 属性,一旦在覆盖函数 pathGeneratorForCorner:withAngle 中使用它,它只使用分配的第一个值。
在我看来,某处有一个环境捕获,尽管它不是闭包,因为它是一个覆盖函数。 (函数可以捕获环境吗?如果可以,我该如何避免?)
到目前为止我所做的无济于事:

非常感谢您的帮助。
问候。 阿尔弗雷多.

所有现代编程都是object-based编程。这是关于 object-based 编程的事情;一个对象类型可以有多个实例,并且每个这样的实例都单独维护其自己的实例属性值。

至此,您的代码和输出之间的关系已经很清楚了:

let mdcRectangleShape = MDCRectangleShapeGenerator()
let customCorner = CustomCorner(radius: 8)

print("step 1 radio=\(customCorner.radius)")
customCorner.radius = 5

print("step 2 radio=\(customCorner.radius)")
mdcRectangleShape.setCorners(customCorner)

print("step 3 radio=\(customCorner.radius)")
let _ = customCorner.pathGeneratorForCorner(withAngle: 10)
nextButton.shapeGenerator = mdcRectangleShape

你的输出是:

Corner initialized with radius=8.0
step 1 radio=8.0
step 2 radio=5.0
step 3 radio=5.0
entering pathGeneratorForCorner with radius 5.0
continuing pathGeneratorForCorner with radius 5.0

是的,嗯,这就是我们期望看到的。您将半径设置为 5,它保持 5

好的,所有其他输出是从哪里来的?

entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0
entering pathGeneratorForCorner with radius 12.0
continuing pathGeneratorForCorner with radius 12.0

这些将来自某些 other CustomCorner 实例,您在其中 notradius 设置为 5.它仍然是默认值,12,你初始化它的方式:

var radius: CGFloat = 12;

至于那些其他实例来自哪里,我不知道。你没有显示足够的代码让我知道。

要确认这一点,请继续打印 CustomCorner 对象 本身 。它将打印其内存地址,这是一个唯一标识符。您会看到您有多个 不同的 CustomCorner 对象。

正如马特的回答中已经提到的,显示的 entering pathGeneratorForCorner with radius 12.0 是您的 customCorner.

的副本

GitHub of Material iOS开始,[MDCRectangleShapeGenerator setCorners:]实现如下:

- (void)setCorners:(MDCCornerTreatment *)cornerShape {
  self.topLeftCorner = [cornerShape copy];
  self.topRightCorner = [cornerShape copy];
  self.bottomRightCorner = [cornerShape copy];
  self.bottomLeftCorner = [cornerShape copy];
}

事实上,它为 setCorners:.

复制了 4 个对象

您的 CustomCorner 继承了 MDCCornerTreatment,符合 NSCopyingMDCCornerTreatment 实现 copyWithZone: 需要符合 NSCopying,但实现不知道其子类的属性。

您可能需要通过覆盖 CustomCorner.

中的 copy(with:) 来修改此默认复制行为
class CustomCorner: MDCCornerTreatment{
    var radius: CGFloat = 12;

    convenience init(radius: CGFloat) {
        self.init();
        self.radius = radius;
        print("Corner initialized with radius=\(self.radius)");
    }
    
    override func copy(with zone: NSZone? = nil) -> Any {
        let newCopy = super.copy(with: zone) as! CustomCorner
        newCopy.radius = self.radius
        return newCopy
    }

    //...
}