Persian
Persian

Reputation: 294

One delegate Two classes

I am using a UISearchController with GoogleMap Autocomplete View controller to send data to my view controllers. I have a Tabbar controller and I want to send the data two my ViewController A and B. I have done all the necessary jobs but only one ViewController gets notified when user has used the UISearchController.

I have tried setting the delegate of each tab to nil when I move to the other tab, For example if I move from ViewController A to B

I will set the delegate of A to nil and then set the delegate of B to itself.

I am kinda new to swift so Can anyone help me understand why isn't this working?

I have tried debugging my code to see is my delegate is nil and it wasn't .

Here is how i set and unset the delegate

 func setDelegate() {

    print("MapViewController is not nil")
    print(resultsViewController?.delegate)
    resultsViewController?.delegate = self
    print(resultsViewController?.delegate)

}

func unSetDelegate() {

    print("MapViewController is nil")
    resultsViewController?.delegate = nil

}

Upvotes: 2

Views: 1245

Answers (1)

Reinier Melian
Reinier Melian

Reputation: 20804

You need an observer pattern, if you need that one class instance notify to a number of other instances you need make an array of delegates (called observers) and register and deregister from that notifier instance class

Further info Wikipedia Observer Pattern

example code

This is the protocol that must implement any observer class

protocol GeotificationsManagerObserver : NSObjectProtocol{
    func nearestGeotificationsHasChanged(pgeotifications:[Geotification])
}

Notifier class

class GeotificationsManager: NSObject {
    
    /**...*//code
    
    fileprivate var observers : [GeotificationsManagerObserver] = []

    /**...*//code

}

Observers methods

extension GeotificationsManager
{
    func addGeotificationsManagerObserver(observer:GeotificationsManagerObserver)
    {
        for currentObs in self.observers {
            if(observer.isEqual(currentObs))
            {
                //we don't want add again
                return
            }
        }
        
        self.observers.append(observer)
    }
    
    func removeGeotificationsManagerObserver(observer:GeotificationsManagerObserver)
    {
        var observerIndex = -1
        for (index,currObserver) in self.observers.enumerated() {
            if(observer.isEqual(currObserver))
            {
                observerIndex = index
                break
            }
        }
        if(observerIndex != -1)
        {
            self.observers.remove(at: observerIndex)
        }
    }
    
    //here make the notification to all observers in observers array
    func nearestsGeotificationsHasChanged()
    {
        for currObserver in self.observers {
            currObserver.nearestGeotificationsHasChanged(pgeotifications: self.getNearesGeotifications())
        }
    }
    
}

Important You must remove the observer once you don't need being notified if not you will have memory issue

Example: You can add a UIViewController as Observer in viewDidAppear and can be removed in viewDidDisappear

Upvotes: 4

Related Questions