Search code examples
iosswiftswift3encapsulation

Data encapsulation and security in Swift


I'm currently studying iOS development in Swift and came across the concept of data encapsulation and security. Let's start with an example:

Class Person {
    private var _weight: Int!

    var weight: Int {
        get {
            return _weight
        }
        set {
            _weight = newValue
        }
    }
}

In the tutorial, I was taught to always make a private var for the purpose of security so the variable cannot be excessed externally and mutate the data. And the instructor also emphasized to explicitly set the getter and setter like above. Writing getter and setter seems very cumbersome to me and it seems like I only need to utilize getter and setter when they are needed. (i.e. getter could be used for read-only property and setter could be used for the purpose of Computed Property).

I wonder if I need to follow this practice all the time or whether I can simply define the property like following:

Class Person {
    var _weight: Int!
}

Solution

  • In Swift, you don't need to declare explicit getters and setters for all of your properties, unless you want to customize their behavior.

    Most of the time, this will work just fine:

    class Person {
        var weight: Int
    }
    

    You can even make a variable read-only publicly, and read-write privately:

    class Person {
        public private(set) var weight: Int
    }
    

    Your instructor's example is useful when you want to customize the behavior of the getters and setters, for example lazily fetching the data from some external source:

    class Person {
        private var _weight: Int!
    
        var weight: Int {
            get {
                if _weight == nil {
                    //fetch _weight from somewhere
                }
                return _weight!
            }
            set {
                _weight = newValue
            }
        }
    }
    

    Private variables are not a security feature. It's trivial to dump the memory of an object and extract private variables from that, and in many languages you can access them even more easily using features like reflection.

    Rather, private variables are for encapsulation. A variable being marked private means "This is an internal interface so do not use it. If you do use it, it's not guaranteed to work, and even if it works now, it might not work in the future." Private variables can also allow the compiler to perform some extra optimizations in some cases, since it knows that the variable will never be accessed anywhere except in this class declaration.