title: Weak self in closures and consequences example
body: <p>I have done abit of research on stackoverflow and apple's documentation about ARC and Weak/Unowned self (<a href="https://stackoverflow.com/questions/24320347/shall-we-always-use-unowned-self-inside-closure-in-swift">Shall we always use [unowned self] inside closure in Swift</a>). I get the basic idea about strong reference cycle and how it is not good as they cause memory leaks. However, I am trying to get my head around when to use Weak/Unowned self in closures. Rather then going into the "theory", I think it would really really help if someone could kindly explain them in terms of the bottom three cases that I have. My questions is </p>
  
  <ol>
  <li><p>Is it OK to put weak self in all of them (I think for case two there is no need because I saw somewhere that UIView is not associated with self?. However, what if I put weak self there, is there anything that can cause me headache?</p></li>
  <li><p>Say if the answer is No, you cant put weak self everywhere in all three cases, what would happen if I do (example response would be much appreciated...For example, the program will crash when this VC ....</p></li>
  <li><p>This is how I am planning to use weakSelf
  Outside the closure, I put weak var weakSelf = self
  Then replace all self in closure with weakSelf?
  Is that OK to do?</p>
  
  <pre><code>Case 1:
  FIRAuth.auth()?.signInWithCredential(credential, completion: {    (user: FIRUser?, error: NSError?) in
      self.activityIndicatorEnd()
      self.performSegueWithIdentifier(SEGUE_DISCOVER_VC, sender: self)
  })
  
  Case 2:
  UIView.addKeyframeWithRelativeStartTime(0.0, relativeDuration: 0.1, animations: {
      self.messageLbl.alpha = 0.5
  })
  
  Case 3: 
  //checkUserLoggedIn sends a request to firebase and waits for a response to see if the user is still authorised
  checkUserLoggedIn { (success) in
      if success == false {
          // We should go back to login VC automatically
  
      } else {        
          self.discoverTableView.delegate = self
          self.discoverTableView.dataSource = self
  
          // Create dropdown menu
          let menuView = BTNavigationDropdownMenu(navigationController: self.navigationController, title: self.dropDownItems.first!, items: self.dropDownItems)
  
          menuView.didSelectItemAtIndexHandler = {[weak self] (indexPath: Int) -&gt; () in
              if indexPath == 0 {
                  self?.mode = .Closest
                  self?.sortByDistance()
  
              } else if indexPath == 1 {
                  self?.mode = .Popular
                  self?.sortByPopularity()
  
              } else if indexPath == 2 {
                  self?.mode = .MyPosts
                  self?.loadMyPosts()
  
              } else {
                  print("Shouldnt get here saoihasiof")
              }
          }
  
      // Xib
          let nib = UINib(nibName: "TableSectionHeader", bundle: nil)
          self.xibRef = nib.instantiateWithOwner(self, options: nil)[0] as? TableSectionHeader
          self.discoverTableView.registerNib(nib, forHeaderFooterViewReuseIdentifier: "TableSectionHeader")
  
          // Set location Manager data
          self.locationManager.delegate = self
          self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
  
          // Check location service status
          if self.locationAuthStatus == CLAuthorizationStatus.AuthorizedWhenInUse {
              // Already authorised
              self.displayMessage.hidden = false
  
          } else if self.locationAuthStatus == CLAuthorizationStatus.NotDetermined {
              // Have not asked for location service before
              let storyboard = UIStoryboard(name: "Main", bundle: nil)
              let vc = storyboard.instantiateViewControllerWithIdentifier("LocationVC") as! LocationVC
              vc.locationVCDelegate = self
              self.presentViewController(vc, animated: true, completion: nil)
  
          } else {
              let alertController = UIAlertController(title: "Enable Location", message: "location is required to load nearby posts", preferredStyle: .Alert)
              let cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
              let settingsAction = UIAlertAction(title: "Settings", style: .Default, handler: { (action: UIAlertAction) in
                  let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
                  if let url = settingsUrl {
                      UIApplication.sharedApplication().openURL(url)
                  }
              })
              alertController.addAction(settingsAction)
              alertController.addAction(cancelAction)
              self.presentViewController(alertController, animated: true, completion: nil)
  
              self.displayMessage.hidden = false
              self.displayMessage.text = "Could not determine your location to find nearby posts. Please enable location Service from settings"
          }
  
          // Styling
          self.refreshBtn.tintColor = COLOR_NAVIGATION_BUTTONS
          self.discoverTableView.backgroundColor = COLOR_DISCOVERVC_TABLEVIEW_BACKGROUND
  
          // Allow navigation bar to hide when scrolling down
          self.hidingNavBarManager = HidingNavigationBarManager(viewController: self, scrollView: self.discoverTableView)
  
          // Allow location to start updating as soon as we have permission
          self.locationManager.startUpdatingLocation()
     }
  }
  </code></pre></li>
  </ol>
  
  <p>--Update-- 
  Most of my code looks like case 3 where everything is wrapped inside a closure that either check if there is internet connectivity before any of the action is taken place. So I might have weak self everywhere??</p>
  
  <p>--Update 2--</p>
  
  <pre><code>Case 4: 
  // The haveInternetConnectivity function checks to see if we can reach google within 20 seconds and return true if we can 
  haveInternetConnectivity { (success) in
      if success == false {
          self.dismissViewControllerAnimated()
      } else {        
          self.label.text = "You are logged in" 
          self.performSegueWithIdentifier("GoToNextVC")
      }
  }
  </code></pre>
  
  <p>Question about case 4. 
  Am I correct to say that even though this closure does not have weak/unowned self, it will never create strong reference (and memory leak) because even if the VC is dismissed before the completion block is executed, Xcode will try to run the code inside the completion block when we have confirmed internet status and will just do nothing (No crash) because self doesn't exist anymore. And once the code reached the last line inside the closure, the strong reference to self would be destroyed hence deallocate the VC? </p>
  
  <p>So putting [weak Self] in that case would just mean that xcode would ignore those lines (as oppose to try and run it and nothing happens) which would mean a better practice but no issues on my hand either way </p>