'Cleaning up delegates in non UIViewControllers

I've been trying something different than the traditional examples for iOS/Swift code. Typically I see the delegate methods being handled in the UIViewController subclasses. What I wanted to try was to keep some of the business logic out of the view controller in it's own Logic class that the UIViewController would use instead. For example:

class LocationLogic : NSObject {
    let manager = CLLocationManager()
    var locationLogicDelegate: LocationLogicDelegate?
    
    override init() {
        super.init()
        manager.delegate = self
    }
    
    func checkWhenInUseLocationServices() {
        if CLLocationManager.authorizationStatus() == .NotDetermined {
            manager.requestWhenInUseAuthorization()
        }
    }

    func startUpdatingLocation() {
        manager.startUpdatingHeading()
    }
    
    func stopUpdatingLocation() {
        manager.stopUpdatingLocation()
    }
    
    deinit {
        println("deinit LocationLogic")
        manager.delegate = nil
    }
}

In the init() method of LocationLogic, I set its class as the delegate. My first question is, do I need to clean up the delegate at all later? I remember reading about circular references but was not sure if this applied. If so, how do I clean it up? I tried cleaning it up in the deinit closure, but what's weird is, in my subclass of UIViewController

class TestViewController: UIViewController {
   var locationLogic = LocationLogic()
}

locationLogic is a property on TestViewController and when TestViewController gets pushed on the stack, I immediately see my "deinit LocationLogic" message getting printed.

So if I need to clean up the delegate, how do I clean it up?



Solution 1:[1]

If you are using a separate object as a delegate, you can keep a strong reference to it from inside the view controller. The delegate itself, however, should have no strong references to the view or whatever object it is delegating for.

In your example above, the TestViewController should have the manager and the locationLogic as its properties. You then do something like this from inside TestViewController:

self.manager.delegate = self.locationLogic

You don't need a CLLocationManager object inside LocationLogic because iOS passes the location manager object to CLLocationManagerDelegate functions when they are called.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1