【发布时间】:2016-08-21 03:49:47
【问题描述】:
我对 stackoverflow 和苹果关于 ARC 和 Weak/Unowned self (Shall we always use [unowned self] inside closure in Swift) 的文档进行了一些研究。我得到了关于强引用循环的基本概念,以及它如何不好,因为它们会导致内存泄漏。但是,我试图弄清楚何时在闭包中使用弱/无主自我。而不是进入“理论”,我认为如果有人可以根据我所拥有的最底层的三个案例来解释它们,那将真的很有帮助。我的问题是
是否可以将弱自我放在所有这些中(我认为对于情况二没有必要,因为我在某处看到 UIView 与自我无关?但是,如果我将弱自我放在那里怎么办,有什么东西会让我头疼吗?
说如果答案是否定的,你不能在所有三种情况下都将弱自我放在任何地方,如果我这样做会发生什么(示例响应将不胜感激......例如,当这个 VC 时程序将崩溃....
-
这就是我打算如何使用weakSelf 在闭包之外,我把 weak var weakSelf = self 然后用weakSelf替换闭包中的所有self? 这样做可以吗?
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) -> () 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() } }
--更新-- 我的大部分代码看起来像案例 3,其中所有内容都包装在一个闭包中,该闭包在执行任何操作之前检查是否存在互联网连接。所以我可能到处都是弱自我??
--更新2--
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")
}
}
关于案例 4 的问题。 我是否正确地说,即使这个闭包没有弱/无主自我,它也永远不会产生强引用(和内存泄漏),因为即使在执行完成块之前关闭 VC,Xcode 也会尝试运行代码当我们确认互联网状态并且什么都不做(没有崩溃)时,在完成块内,因为 self 不再存在。一旦代码到达闭包内的最后一行,对 self 的强引用就会被破坏,从而释放 VC?
所以在这种情况下放置 [weak Self] 只会意味着 xcode 会忽略这些行(因为反对尝试运行它并且没有任何反应),这意味着更好的做法,但无论哪种方式都没有问题
【问题讨论】:
标签: swift closures automatic-ref-counting