【问题标题】:Property setter called instead of getter in switch (Xcode 9.3 & 9.4)在开关中调用属性设置器而不是获取器(Xcode 9.3 和 9.4)
【发布时间】:2018-06-06 17:20:02
【问题描述】:

考虑以下对象:

enum SetType: String {
    case anaerobic, isometric
}

class RealmSet: Object {
   @objc dynamic private var setType: String = ""
    var type: SetType {
        get {
            guard let unwrappedSetType = SetType(rawValue: setType) else {
                return .anaerobic
            }
            return unwrappedSetType
        }
        set {
            self.setType = newValue.rawValue
        }
    }
}

protocol ExerciseSet {
    var setType: SetType { get }
}

class Exercise: Object {
   private let setsValues = List<RealmSet>()
   var sets: [ExerciseSet] {
        var sets = [ExerciseSet]()
        for setValue in self.setsValues {
            switch setValue.type {
            case .anaerobic:
                // Do Something

            case .isometric:
                // Do Something
            }
        }

        return sets
    }
}

发生的情况是,当我尝试迭代 setsValues 的数组并执行 switch 以发现 RealmSet 的类型,而不是调用来自 RealmSettype getter 属性时,而是调用 setter。由于这个对象是一个 Realm 对象,应用程序会立即崩溃,因为我没有运行写事务,这是真的,因为我只需要访问属性 getter,而不是它的 setter。

这种情况最奇怪的是当 Xcode 版本低于 9.3 时不会发生这种情况。这只发生在 Xcode 9.3 和 9.4 中。当我使用 Xcode 9.2 时,一切正常。

我不知道问题出在哪里。如果是 Realm lib,Xcode 版本 9.3 和 9.4 或什么的一些变化。

【问题讨论】:

  • 您确定不是 switch 语句的主体导致崩溃吗?您是否尝试仅在两个 case 语句中打印某些内容,以确保您不会意外修改那里的任何内容?
  • @DávidPásztor 是的。我还在RealmSet type 属性的gettersetter 内设置了一个断点,当执行切换时,它到达设置器断点。我也为 XCode 9.2 做了这个,但是在这个版本中,getter 被调用了。
  • 我试图重现您的问题,但是当 Exercise.setsValues 是私有的时,您应该如何向它添加值? sets 是一个访问 setsValues 的计算属性,所以我似乎无法找到一种方法来为其中任何一个添加值从而触发错误。
  • @DávidPásztor setsValues 是私有属性,因为您不应该在模型之外更改其值。这就是我创建这个计算属性sets 的原因,因为它管理对这个 List 属性的访问和修改。由于两者(setsValuessets)属于同一类,我看不出有任何原因导致您因私人保护而无法访问。
  • 我的意思是,如果您没有展示如何从 setsValues 内部修改 setsValues,则很难重现您的问题。您应该修改问题中的代码以包含minimal reproducible example

标签: swift realm xcode9.3 xcode9.4


【解决方案1】:

不确定到底哪里出了问题¹,但在同一个类中有一个读/写 var type 和一个单独的属性 setType 对我来说真的很可疑。尝试将setType 重命名为rawSetType 之类的名称,以至少确保它不会与type 属性发生冲突。

¹ 必须与 Realm.Object 是一个 Objective-C 类相关,这意味着对于 type 属性将有一个名为 setType 的设置器。

【讨论】:

  • 我已重命名所有这些 var 以确保这不是名称冲突,并且与 var 名称无关。
【解决方案2】:

对于那些面临同样问题的人,在处理 Realm 时不要使用get set。 Realm 通过 KVO 访问属性,因此在某些情况下它会丢失并导致这种错误。使用get-only 属性结合函数来设置此属性,而不是使用get set

【讨论】:

    猜你喜欢
    • 2015-07-20
    • 1970-01-01
    • 2014-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    相关资源
    最近更新 更多