Search code examples
iosswiftnetwork-programmingalamofire

weak self always nil in asynchronous closure Alamofire


When I use below version of code I am able to see the self object(it is non nill aways) and do the other processing stuff.

Without converting self to weak self

    Alamofire.request(some url).responseJSON {  response in

        self.resolvedURLString = "ff"
        print("==\(self.resolvedURLString)")
    }

But to avoid retain cycles or for safety way (using weak self always in closures) I am using below version of code.

By converting self to weak self

    Alamofire.request(some url).responseJSON { [weak self] response in

        guard let strongSelf = self else { return }

        strongSelf.resolvedURLString = "ff"
        print("==\(strongSelf.resolvedURLString)")
    }

but here always self become nil , I never able to print the value of resolvedURLString. How to make self as strong self or how to retain the self until closure execution ends?

EDIT: From AppDelegate i initiazed NetworkManager , from this class i call NetworkDownloader, in this class the actual call will happen

AppDelegate.M

if let networkManager = self.networkManager {
    networkManager.downloadDataToCache()
}

NetworkManager

let __areaDownloader = AreaDownloader(backgroundContext: backgroundContext, withDelegate: nil)
__areaDownloader.download(withSuccess: {_ in
    //Write code for core data
    self.isAreaCachingIsComplete = true
    self.checkNotificationsForCacheComplete()

}, failure: {})

class AreaDownloader: NetworkDownloader

    override func download(withSuccess successBlock: SuccessWithJsonType?, failure failureBlock: FailureType?) {

            Alamofire.request(some url).responseJSON { [weak self] response in

                guard let strongSelf = self else { return }

                strongSelf.resolvedURLString = "ff"
                print("==\(strongSelf.resolvedURLString)")
            }
}

Solution

  • Whatever object is that self refers to has gone by the time the Alamofire's completion request handler gets executed. You need to keep a strong reference to self somewhere until after the response handler has run. In your first example with the strong self the closure itself provides the strong reference. In the second example with weak self nothing does.

    What option you choose is dependent on circumstances. Looking at your code, such as it is, you don't keep a reference to the Alamofire request anywhere so you'll probably be OK with the your first option - the object referred to by self doesn't keep a strong reference to the request either directly or indirectly, so there's no ownership cycle.