我对stackoverflow和苹果关于ARC和弱/无主自我的文档做了一些研究(
Shall we always use [unowned self] inside closure in Swift
). 我得到了关于强引用循环的基本概念,以及它如何不好,因为它们会导致内存泄漏。然而,我正在努力弄清楚什么时候在闭包中使用弱/无主自我。我认为,如果有人能用我所掌握的最底层的三个案例来解释它们,那就真的会有帮助。我的问题是
-
把脆弱的自我放在所有的里面可以吗(我认为对于案例二没有必要,因为我在某个地方看到UIView与自我无关?但是,如果我把脆弱的自己放在那里,有什么东西会让我头痛吗?
-
如果答案是否定的,那么你不能在所有三种情况下都把脆弱的自我放在任何地方,如果我这样做会发生什么(例如,非常感谢你的回答…例如,当这个VC。。。。
-
这就是我计划使用weakSelf的方式
在闭包之外,我将弱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")
}
}
我正确地说,即使这个闭包没有弱/无主自我,它也不会创建强引用(和内存泄漏),因为即使VC在执行完成块之前被解除,当我们确认了互联网状态时,Xcode会尝试在完成块内运行代码,并且什么也不做(没有崩溃),因为自我不再存在。一旦代码到达闭包内的最后一行,对self的强引用就会被破坏,从而释放VC?
因此,在这种情况下使用[weak Self]只意味着xcode将忽略这些行(与尝试运行它相反,什么也没有发生),这意味着更好的实践,但我手头也没有问题