-1

Consider the following objects:

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
    }
}

What happens is that when I try to iterate this array of setsValues and perform a switch to discover which is the kind of that RealmSet, instead type getter property from RealmSet gets called, the setter is called instead. As this object is a Realm object, the application instantly crashes because I'm not running a write transaction, which is true because I only need to access the property getter, not its setter.

The most strange of this situation is that this doesn't happen when Xcode versions is lower than 9.3. This only happens in Xcode 9.3 and 9.4. When I use Xcode 9.2 everything works perfectly.

I don't know where is the problem. If it is Realm lib, some change in Xcode versions 9.3 and 9.4 or what.

Cœur
  • 37,241
  • 25
  • 195
  • 267
GGirotto
  • 848
  • 2
  • 10
  • 31
  • Are you sure that it's not the body of the `switch` statement's cases that are causing the crash? Did you try only printing something inside both `case` statements, making sure that you're not modifying anything there by accident? – Dávid Pásztor Jun 06 '18 at 17:27
  • @DávidPásztor Yes. I've also set a breakpoint inside `getter` and `setter` of `RealmSet` `type` property and when the switch is executed it reaches the setter breakpoint. I've also done this for XCode 9.2, but in this version, the getter is called. – GGirotto Jun 06 '18 at 18:01
  • I was trying to reproduce your issue, but how are you supposed to add values to `Exercise.setsValues`, when it is private? `sets` is a computed property accessing `setsValues`, so I can't seem to find a way to even add values to either of those and hence to trigger the bug. – Dávid Pásztor Jun 06 '18 at 19:00
  • @DávidPásztor `setsValues` is a private property because you are not supposed to change its values outside the model. That's why the I've created this computed property `sets` because it manages the access and modifications to this List property. Since both (`setsValues` and `sets`) are in the same class, I don't see any reasons why you cannot access due to private protection. – GGirotto Jun 07 '18 at 13:39
  • What I meant is without you showing how you're modifying `setsValues` from inside `sets` it's hard to reproduce your problem. You should modify the code in your question to include a [mcve]. – Dávid Pásztor Jun 07 '18 at 13:43

2 Answers2

0

Not sure where exactly things go wrong¹ but having a read/write var type and a separate property setType in the same class sounds really suspicious to me. Try renaming setType to something like rawSetType to at least be sure it doesn't clash with the type property.

¹ Must be related to Realm.Object being an Objective-C class, meaning that for type property there would be a setter named setType.

Gleb A.
  • 1,180
  • 15
  • 24
  • I've renamed all this vars to ensure that was not a name conflict, and it's not something related to the var name. – GGirotto Jun 07 '18 at 13:36
0

For those facing the same problem, do not use get set when handling with Realm. Realm access properties through KVO, so in some situations it gets lost and cause this kind of error. Use get-only properties combined with functions to set this properties instead using get set

GGirotto
  • 848
  • 2
  • 10
  • 31