【问题标题】:swift UIColor extension of "cannot assign to value: 'self' is immutable"swift UIColor 扩展“无法赋值:‘self’是不可变的”
【发布时间】:2017-12-14 08:36:54
【问题描述】:

我写了一个UIColor的扩展来直接改变alpha:

public extension UIColor {

    public var rgbaComponents: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
        var components: [CGFloat] {
            let c = cgColor.components!
            if c.count == 4 {
                return c
            }
            return [c[0], c[0], c[0], c[1]]
        }
        let r = components[0]
        let g = components[1]
        let b = components[2]
        let a = components[3]
        return (red: r, green: g, blue: b, alpha: a)
    }

    public var alpha: CGFloat {
        get {
            return cgColor.alpha
        }
        set {
            var rgba = rgbaComponents
            self = UIColor(red: rgba.red  // error here: "cannot assign to value: 'self' is immutable"
            , green: rgba.green, blue: rgba.blue, alpha: newValue)
        }
    }
}

但是有一个错误:

无法赋值:'self' 是不可变的

但是将日期延长以分配给自己是可以的

public extension Date {

    public var day: Int {
        get {
            return Calendar.current.component(.day, from: self)
        }
        set {
            let allowedRange = Calendar.current.range(of: .day, in: .month, for: self)!
            guard allowedRange.contains(newValue) else { return }

            let currentDay = Calendar.current.component(.day, from: self)
            let daysToAdd = newValue - currentDay
            if let date = Calendar.current.date(byAdding: .day, value: daysToAdd, to: self) {
                self = date // This is OK
            }
        }
    }
}

是因为 UIColor 来自 NSObject 并且 Date 是一个 Swift 结构吗?根本原因是什么?

【问题讨论】:

    标签: swift struct extension-methods nsobject


    【解决方案1】:

    你是对的,因为 Date 是一个结构(值类型),而 UIColor 是一个类(引用类型)。

    当您为结构分配 self 时,您实际上只是在更新该结构的所有属性(简单地说),因此实际内存位置不会改变。所以你实际上并没有改变 self 本身的价值。

    但是,当您为某个类分配给 self 时,您正在内存中创建一个全新的类,因此当您将其分配给 self 时,您是在尝试改变 self。即使允许任何持有对颜色的引用的东西如何处理它,因为它们仍然持有对原始类的引用。

    【讨论】:

    • 不幸的是,我认为没有使用扩展的解决方案。您无法更改 UIColor 的 alpha 而不创建新的,并且您无法更改 self 因为它是不可变的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-24
    • 2014-12-13
    • 2015-06-21
    • 2016-01-10
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    相关资源
    最近更新 更多