漆雕古代 发表于 2017-3-12 20:45:43

Swift 关于 willset 的 问题

本帖最后由 漆雕古代 于 2017-3-12 20:48 编辑

最近在看一点swift遇到一个问题,不知道该怎么解决,代码如下

class NamedShape {
    var numberOfSides: Int = 0
    var name: String
   
    init(name: String) {
      self.name = name
    }
   
    func simpleDescription() -> String {
      return "A shape with \(numberOfSides) sides."
    }
}

class Square: NamedShape {
    var sideLength: Double
      
    init(sideLength: Double, name: String) {
      self.sideLength = sideLength
      super.init(name: name)
      numberOfSides = 4
    }
   
    func area() ->Double {
      return sideLength * sideLength
    }
      
    override func simpleDescription() -> String {
      return "A square with sides of length \(sideLength)."
    }
}


class EquilateralTriangle: NamedShape {
    var sideLength: Double = 0.0
   
    init(sideLength: Double, name: String) {
      self.sideLength = sideLength
      super.init(name: name)
      numberOfSides = 3
    }
   
    var perimeter: Double {
      get {
            return 3.0 * sideLength
      }
      set {
            self.sideLength = newValue / 3.0
      }
    }
   
    override func simpleDescription() -> String {
      return "An equilateral triagle with sides of length \(sideLength)."
    }
}



class TriangleAndSquare {
    var triangle: EquilateralTriangle {
      willSet {
            square.sideLength = newValue.sideLength
      }
    }
            
    //var triangle.sideLength { // 由于用perimeter改变triangle的sideLength属性,导致重新设置的不是triangle而是triangle.sideLength
      //willSet {
            //print(newValue.sideLength)
            //square.sideLength = newValue
      //}
      //didSet {
            //print("triangle a change")
      //}
    //}
   
    var square: Square {
      willSet {
            print(newValue.sideLength)
            triangle.sideLength = newValue.sideLength
      }
    }
      
    init(size: Double, name: String) {
      self.square = Square(sideLength: size, name: name)
      self.triangle = EquilateralTriangle(sideLength: size, name: name)
    }
}


//第一次test
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
//第二次test
triangleAndSquare.square = Square(sideLength: 50, name: "larger square")
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)
//第三次test测试setter设置的值会不会影响willSet
triangleAndSquare.triangle.perimeter = 60
print(triangleAndSquare.square.sideLength)
print(triangleAndSquare.triangle.sideLength)


输出如下

//第一次test输出结果
10.0
10.0
//第二次test输出结果
50.0
50.0
50.0
//第三次test输出结果
50.0
20.0


这段代码出自苹果的官方教程,目的在于让等边三角形和正方形的边长随时保持相等。
本来是一切ok的,但是我想在EquilateralTriangle中有一个perimeter属性拥有getter和setter的功能,可以直接更改sideLength的值,所以在这种情况下willSet不会触发,代码的目是无法达成的吧。

然后一试果然如此,自己尝试解决了一下,但是依旧不行,我自己思考出来的代码无法运行,上网搜索资料页偏少。


我就是想知道有没有可以解决这个问题的办法?

cyndiwants 发表于 2017-9-13 23:15:56

顶楼主,哈哈,祝你早日解决

cyndiwants 发表于 2017-9-16 11:19:18

看着好难啊,楼主

cyndiwants 发表于 2017-9-18 15:44:50

顶楼主,谢谢分享

cyndiwants 发表于 2017-9-18 15:45:25

回复失效了?啊?

longlive 发表于 2017-9-18 21:54:05

谢谢楼主分享,哈哈

漆雕古代 发表于 2017-9-25 21:07:30

cyndiwants 发表于 2017-9-18 15:45
回复失效了?啊?

我的天啊,半年了居然有人理我了,感动

漆雕古代 发表于 2017-9-25 21:08:02

longlive 发表于 2017-9-18 21:54
谢谢楼主分享,哈哈

还没解决呢其实哈哈

bing_home 发表于 2017-11-1 15:37:27

感谢楼主

zhangyuxuan 发表于 2017-11-1 15:51:28

还有奖励马

willcipher 发表于 2017-11-26 18:24:29

祝解决

bing_home 发表于 2017-11-27 22:08:40

感谢楼主鱼币奖励

zhangyuxuan 发表于 2017-11-27 22:14:02

感谢楼主

zero月蚀的假面 发表于 2017-12-21 15:16:16

这么久还没大神来解决{:10_250:}

mmdn 发表于 2018-1-3 15:21:57


顶楼主,谢谢分享

chijiahao 发表于 2018-1-19 16:22:11

蒂{:5_91:{:5_91:}{:5_100:}

robinyunhao 发表于 2018-3-13 19:03:45


robinyunhao 发表于 2018-3-22 19:08:20

wyf345491656 发表于 2018-3-24 13:40:49

新人帮顶一发~

学学看看 发表于 2018-11-30 10:41:14

页: [1] 2 3
查看完整版本: Swift 关于 willset 的 问题