Ryan Ryan - 4 months ago 46
iOS Question

Writing a Custom Setter for my Variable - Swift

I am trying to run a Setter on a property when it changes, that will then also affect the logic in that class:

Here is how it used to look in Objective - C:

@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;


Set Method for fetchedResultsController:

- (void)setFetchedResultsController:(NSFetchedResultsController *)newFetchResultsContrller
{
NSFetchedResultsController *oldfetchResultsController = _fetchedResultsController;
if (newFetchResultsContrller != oldfetchResultsController) {
_fetchedResultsController = newFetchResultsContrller;
newFetchResultsContrller.delegate = self;
if ((!self.title || [self.title isEqualToString:oldfetchResultsController.fetchRequest.entity.name]) && (!self.navigationController || !self.navigationItem.title)) {
self.title = newFetchResultsContrller.fetchRequest.entity.name;
}
if (newFetchResultsContrller) {

[self performFetch];
} else {

[self.tableView reloadData];
}
}
}


Here is my attempt in Swift. However I cannot get the newFetchResultsController, thus cannot complete rest. Is this the right way of setting a property in swift ? How can I do the same principle as above shown in Objective C in Swift?

var fetchedResultsController:NSFetchedResultsController! {
willSet {
println("Set fetchedResultsController Called")
self.fetchedResultsController.delegate = self
performFetch()
}
}

Answer

UPD:
Today with Swift 3.0 your logic can be reimplemented, you may have single plain stored property with only didSet value observer specified like this:

var fetchedResultsController:NSFetchedResultsController? {
    didSet(oldfetchResultsController) {
        // If value BEFORE it was set is not identical to value AFTER it was set.
        if oldfetchResultsController !== fetchedResultsController {
            // Let's assume there is such method.
            if fetchedResultsController.isBadAndNotSuitable == false {
                // Do your stuff here.
            } else {
                // If you want to override value that was set
                // without observers being called, you can just set
                // your property inside didSet like:
                fetchedResultsController = nil
                // Or, if you don't want to change value:
                fetchedResultsController = oldFetchedResultsController
                // this won't cause willSet to fire and your property
                // will preserve its value.
            }
        } 
    }
}

As it were in 2014:
You may write it like this:

var _fetchedResultsController:NSFetchedResultsController? = nil
var fetchedResultsController:NSFetchedResultsController? {
    get {
        return _fetchedResultsController
    }
    set (aNewValue) {
        if (_fetchedResultsController != aNewValue)
        {
            _fetchedResultsController = aNewValue
        }
    }
}

With this approach you can prevent value to be set. So, for example, if there was a property on NSFetchedResultsController called isBadAndNotSuitable you could write:

set (aNewValue) {
    if (aNewValue.isBadAndNotSuitable)
    {
        NSLog("Don't set, it's bad")
    }
    else
    {
        _fetchedResultsController = aNewValue
    }
}