Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsafe mutable addressor crash

Tags:

swift

I have a struct and sometimes, for some users, there will be a crash when trying to access a variable of that type.

struct AppSettings {
    var mute:Bool {
        didSet {
           if mute != oldValue {
               let savedSettings = NSUserDefaults.standardUserDefaults()
               savedSettings.setBool(mute, forKey: KEY_SETTING_MUTE)                   
           }
        }
    }

    init() {
        let savedSettings = NSUserDefaults.standardUserDefaults()
        if let savedMute = savedSettings.objectForKey(KEY_SETTING_MUTE) as? Bool {
            mute = savedMute
        } else {
            mute = false
        }      
    }

}
var appSettings = AppSettings()

And someplace during startup of the app it sometimes crashes

if appSettings.mute {  // This will sometimes cause a crash
}                      // in AppDelegate or the methods it calls

This is only for some users and I cannot seem to reproduce it. Not being to reproduce it is the worst because it leaves me with nothing to work with.

Searching for unsafe mutable addressor as an error doesn't help because there are almost no results.

like image 623
TimSim Avatar asked Apr 07 '17 13:04

TimSim


1 Answers

I think you solution is over engineered and difficult to understand or debug. I've been using a similar solution in my apps for a few years now to manage session state and wish to share with you. It's something you could lift straight from here and implement and be trouble free.

I work on a Session principle meaning the values which I wish to store and read go through a solid Session class and leave no room for error.

Here is how it's used from anywhere in the application.

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    // how to set the value to be stored in userdefaults
    Session.HasMuted = true
    
   // two example of how to read the value 
    if Session.HasMuted == true {
        print("has muted")
    }
    
    if Session.HasMuted == false {
        print("has not muted")
    }
}

Here is the Session class

class Session {
    class var HasMuted: Bool {
        get {
            guard let HasMuted = UserDefaults.standard.object(forKey: SessionSpace.HasMuted) as? Bool else {
                return false
            }

            return HasMuted
        }
        set {
            UserDefaults.standard.set(newValue, forKey: SessionSpace.HasMuted)
        }
    }
}

and the accompanying Session Space struct

struct SessionSpace {
    static let HasMuted = "HasMuted"
}

I would consider adjusting this to suit your style, I'm not a big fan of capital letters for key strings etc, this is a more elegant readable and implement and forget solution. You can extend this by adding a setter / getter block and key string in the session space block and again use from anywhere in the app in seconds knowing it's trouble free and robust. Let me know if you need any more help. Hope you adopt it and save it to snippets.

like image 180
latenitecoder Avatar answered Nov 03 '22 16:11

latenitecoder