Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nil check inside getter method in swift?

I have an array in my view controller. It should be allocated only if it is nil otherwise it should return the existing value.

Objective C equivalent:

- (NSArray*)states{
     if(!_states)
     {
         _states = //read files from json and assigned to array
     }
     return _states;
}

I have to achieve this in swift. I tried with stored property but not able to achieve this

what is the best way to achieve this

like image 238
jailani Avatar asked Mar 16 '16 07:03

jailani


3 Answers

It can be something like that:

class Whatever {
    private(set) var _states: [AnyObject]?
    var states: [AnyObject] {
        get{
            if let st = _states {
                return st
            }
            else {
                // Read from file
                _states = ....
                return _states!
            }
        }
    }
}

In SWIFT there is no concept of instance variable, but just properties, by writing this private(set) var _states: [AnyObject]? we are saying that _states can't be written from outside our class, but just inside. Then we create a readonly property which duty is read our _states bind it to st if it is not nil or fill it with data.
There is a more SWIFTY way to do that called lazy properties:

class Whatever {
    lazy var states: [AnyObject] = {
        return array read from file
    }()
}

By using lazy, we are saying to create that array only at the first call to the property, once is set it will never be created again, but just returned. Basically it will not pass again to the array creation from the file.

like image 187
Andrea Avatar answered Nov 12 '22 12:11

Andrea


we can use like this also, in Swift 3.0.

private var _designContentViewController: DesignContentViewController?

var designContentViewController: DesignContentViewController? {
    get {
        if _designContentViewController == nil {
            _designContentViewController = DesignContentViewController()
            self.view.addSubview((_designContentViewController?.view)!)
            _designContentViewController?.view.isHidden = true
            _designContentViewController?.view.backgroundColor = UIColor.white
        }
        return _designContentViewController

    }
    set {
        _designContentViewController = newValue
    }
}
like image 28
Ankit Sharma Avatar answered Nov 12 '22 11:11

Ankit Sharma


You go in two steps. You use a stored property like _states which contains an optional array. Then you have a computed property states which accesses the _states optional array and either returns the unwrapped value or loads _states first.

like image 35
gnasher729 Avatar answered Nov 12 '22 10:11

gnasher729