Я сделал исследование исследований stackoverflow и документации Apple относительно ARC и Weak/Unowned (Shall we always use [unowned self] inside closure in Swift). Я получаю основную идею о сильном эталонным цикле и, как это не хорошо, поскольку они вызывают утечки памяти. Тем не менее, я пытаюсь раздобыть голову, когда нужно использовать Weak/Unowned self в закрытии. Вместо того, чтобы зайти в «теорию», я думаю, что это действительно помогло бы, если бы кто-нибудь мог любезно объяснить их в терминах нижних трех случаев, которые у меня есть. Мои вопросыСлабый «я» в замыканиях и пример последствий
Можно ли поставить слабый себя во всех из них (я думаю, что для случая два нет необходимости, потому что я где-то видел, что UIView не связан с самими собой ?. Однако, что если я ставлю слабый сам, есть ли что-нибудь, что может вызвать у меня головную боль?
Скажите, есть ли ответ «Нет», вы не можете ставить слабое «я» во всех трех случаях, что произойдет, если я это сделаю (например, ответ будет очень оценен. Например, программа выйдет из строя, когда этот VC ....
Вот как я планирую использовать weakSelf За пределами закрытия, я положил слабый var 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() } }
--Update-- Большая часть моего кода выглядит случай 3, где все завернутый внутри закрытия, что либо проверить, есть ли подключение к Интернету, прежде чем какой-либо из действий место. Таким образом, я мог бы иметь слабое я везде?
--update 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 попытается запустить код внутри блока завершения, когда мы подтвердим статус интернета и ничего не сделаем (без сбоев), потому что само больше не существует. И как только код достигнет последней строки внутри закрытия, сильная ссылка на «я» будет уничтожена, а значит, освободит VC?
Так положить [слабое Атман] в этом случае будет просто означать, что Xcode будет игнорировать эти строки (как противостоять, чтобы попытаться запустить его и ничего не происходит), что будет означать лучшую практику, но никаких проблем на моей руке либо образом
Не могли бы вы рассказать о том, что вы подразумеваете под «не предлагает никакой пользы». Кроме того, справедливо ли говорить, что любое закрытие, которое включает любой вид, ожидающий от интернет-запроса, всегда нуждается в слабом или незанятом себе? И правильно ли, что почти во всех случаях это было бы слабым я? – user172902
Исключительные ссылки в закрытии 'animation', не предлагающие утилиту: Закрытие' animation', предоставленное 'animateWithDuration', не является обработчиком завершения, который запускается позже (хотя есть отдельное закрытие' завершения', но это отдельный шар из воска в целом). Он вызывается немедленно, и анимация инициируется, но закрытие не содержит никаких сильных ссылок на 'self' на время анимации. – Rob
Re сетевые блокировки всегда нуждаются в слабой/незаслуженной: Нет, это, конечно, не так.Например, вы можете сделать что-то в этом закрытии, которое должно выполняться _must_ (например, обновлять локальную db в отношении завершения сетевого запроса, сохранять загруженное изображение в кеш и т. Д.). Используйте только слабый, если вам не нужно/нужно, чтобы код в закрытии сохранял ссылку на объект_ (например, вы просто обновляете пользовательский интерфейс, но не обновляете кеши или базы данных или структуры моделей). Не просто бездумно используйте «слабый»: посмотрите, что находится в закрытии, и решите, должно ли оно быть (или должно быть) слабым или нет. – Rob