【问题标题】:Cannot assign to property: 'self' is immutable swift error无法分配给属性:“自我”是不可变的快速错误
【发布时间】:2018-10-09 18:35:28
【问题描述】:

在我的应用程序中,我创建了一个名为“Positions”的协议,并扩展了 UIView 类以符合此协议,以便向 UIView 类添加一些属性。我使用了下面的代码。

import Foundation
import UIKit

protocol Positions {
    var initialPositions: [CGRect] {get set}
    var finalPositions: [CGRect] {get set}
    var positionsAreDefined: Bool {get}
}

public enum PositionsType {
    case initial
}

private var initialPositionKey: UInt = 0
private var finalPositionKey: UInt = 0

extension Positions {
    var initialPositions: [CGRect] {
        get {
            if objc_getAssociatedObject(self, &initialPositionKey) != nil {
                return objc_getAssociatedObject(self, &initialPositionKey) as! [CGRect]
            } else {
                return [] as! [CGRect]
            }

        }
        set {
            objc_setAssociatedObject(self, &initialPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    var finalPositions: [CGRect] {
        get {
            if objc_getAssociatedObject(self, &finalPositionKey) != nil {
                return objc_getAssociatedObject(self, &finalPositionKey) as! [CGRect]
            } else {
                return [] as! [CGRect]
            }
        }

        set {
            objc_setAssociatedObject(self, &finalPositionKey, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
        }
    }

    var positionsAreDefined: Bool {
        get {return initialPositions.count != 0 && finalPositions.count != 0 && initialPositions.count == finalPositions.count}
    }

    var positionsCount: Int {
        get {return initialPositions.count}
    }
}

extension UIView: Positions {}

好吧,今天我尝试使用一种新方法来扩展 UIView 类,该方法更改了我添加的属性,但是编译器在我尝试修改属性值的那一行给了我这个错误:

无法分配给属性:'self' 是不可变的

方法如下:

public func horizontallyInContainer(withShift shift: CGFloat, forExpansionNumber index: Int, forPositionType type: PositionsType) {
    if self.positionsAreDefined && self.superview != nil {
        if type == .initial {

            var newPositions = self.initialPositions
            newPositions[index].origin.x = self.superview!.bounds.width * 0.5 - self.bounds.width + shift
            self.initialPositions = newPositions //Here happens the error

        } else {

            var newPositions = self.finalPositions
            newPositions[index].origin.x = self.superview!.bounds.width * 0.5 - self.bounds.width + shift
            self.finalPositions = newPositions //Also here happens

        }
    }
}

谁能解释一下这个错误的性质?

【问题讨论】:

  • 非类绑定协议具有值语义,因此必须使用 mutating 修饰符声明任何变异函数,就像它们在结构定义中一样。
  • 如果您要使用objc_getAssociatedObject 和其他Objective C 运行时特性,您需要将其设为类绑定协议。否则它会起作用,但你会注意到奇怪的行为。结构被装箱到 __SwiftValue 中,它可以被 ObjC 运行时使用,但它们的对象标识不稳定。对象标识是 ObjC 运行时用作其关联对象表中的键的对象。
  • @Carcigenicate 我编辑了我的帖子
  • @Alexander 你建议我应该把关键字“mutating”放在“horizo​​ntallyInContainer”方法声明之前吗?
  • @Alexander 你能解释一下我怎样才能使它成为一个类绑定协议吗?

标签: ios swift properties self


【解决方案1】:

使协议成为引用类型

protocol Positions: AnyObject {

【讨论】:

  • 好的,谢谢,它起作用了...你能解释一下这是做什么的,也许可以指出我可以读到的一些东西,只是为了不要再次陷入同样的​​境地错误? :)
  • Swift Language Guide : Protocols中讨论过,但是在最新版本中推荐符合AnyObject而不是抽象class
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 1970-01-01
  • 2015-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多