I get a nil when I use self in block.But self does't free

Viewed 164

I use an viewController which inherit BaseViewController. The function "monitorNetworkStatus()" is invoked in BaseViewController's method "viewDidLoad".

private func monitorNetworkStatus() {
        ReachabilityManager.shared.startMonitoring { [weak self] (status, presentingVC) in

            print(self?.description)

        }
    }
ReachabilityManager is a singleton。The startMonitoring function like this
    func startMonitoring(reachabilityStatus: @escaping (_ status: AFNetworkReachabilityStatus, _ presentingVC: UIViewController?) -> Void) {

        AFNetworkReachabilityManager.shared().setReachabilityStatusChange { [weak self] (status) in
            if status != self?.networkStatus {
                // Only notify when status toggling between reachable and not reachable
                if (self?.networkStatus == .notReachable &&
                    (status == .reachableViaWiFi || status == .reachableViaWWAN)) ||
                    status == .notReachable {
                    reachabilityStatus(status, self?.getPresentingViewController())
                }

                self?.networkStatus = status
            }
        }

        AFNetworkReachabilityManager.shared().startMonitoring()
When net status changes it will print nil occasionally.
1 Answers

The startMonitoring method takes in a closure which holds a weak reference to your view controller's instance. This closure lets ReachabilityManager's singleton instance know what needs to happen whenever network status changes.

Passing a weak reference to this closure ensures that the memory occupied by your view controller instance can be freed when it is no longer being used, thus preventing a potential memory leak.

At times, your view controller will get garbage collected when it is dismissed (or no longer being used elsewhere), but the singleton instance of ReachabilityManager (which outlives your view controller) will still call the closure that was passed to the startMonitoring method earlier. Since your view controller has been garbage collected, self will be nil in this case and you will see nil being printed occasionally.

Were the closure holding a strong reference to your view controller, you would probably be facing memory leaks, since your view controller will not get garbage collected when dismissed.

Related