La faiblesse de l'autonomie dans les fermetures et les conséquences exemple
J'ai fait abit de la recherche sur stackoverflow et la documentation d'apple à propos de l'ARC et de la Faiblesse/Propriétaire de l'auto (Doit-on toujours utiliser [propriétaire d'auto] à l'intérieur fermeture à Swift). Je reçois l'idée de base au sujet de la solidité de cycle de référence et comment il n'est pas bon car ils provoquent des fuites de mémoire. Cependant, je suis en train d'essayer d'obtenir ma tête autour de quand utiliser Faibles/Propriétaire de l'auto dans les fermetures. Plutôt que d'aller dans la "théorie", je pense qu'il serait vraiment vraiment aider si quelqu'un pouvait m'expliquer en termes de bas de trois cas que j'ai. Ma questions est
-
Est-il correct de mettre la faiblesse de l'autonomie dans chacun d'eux (je pense que pour le cas de deux il n'est pas nécessaire parce que j'ai vu quelque part que UIView n'est pas associée à soi-même?. Cependant, ce que si je mets de la faiblesse de l'autonomie de là, il n'y a rien qui peut me causer des maux de tête?
-
Dire si la réponse est Non, vous ne pouvez pas mettre la faiblesse de soi partout, dans tous les trois cas, qu'adviendrait-il si je n' (exemple de réponse serait très appréciée...Par exemple, le programme crash lors de ce CR ....
-
C'est de cette façon j'ai l'intention d'utiliser weakSelf
En dehors de la fermeture, j'ai mis de la faiblesse de la var weakSelf = auto
Ensuite, remplacer tous les auto fermeture avec weakSelf?
Est-ce que ça à faire?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--
La plupart de mon code ressemble cas 3 où tout est enveloppé à l'intérieur d'une fermeture qui soit de vérifier si il existe une connectivité internet avant tout de l'action s'est déroulée. J'ai la faiblesse de l'auto partout??
--Mise à jour 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")
}
}
Question à propos de l'affaire 4.
Ai-je raison de dire que, même si cette fermeture n'a pas de faiblesse ou propriétaire de l'auto, il ne sera jamais à créer une forte référence (et la fuite de mémoire) car même si le VC est licencié avant la fin de bloc est exécuté, Xcode va tenter d'exécuter le code à l'intérieur de l'achèvement de bloc lorsque nous avons confirmé l'état de l'internet et ne rien faire (Pas de plantage) parce que le moi n'existe plus. Et une fois que le code a atteint la dernière ligne à l'intérieur de la clôture, la référence forte à l'autonomie serait détruit donc de libérer le VC?
Afin de mettre [faible Auto] dans ce cas serait juste de dire que xcode ne tiendrait pas compte de ces lignes (que s'opposer à l'essayer et de le lancer et il ne se passe rien), qui serait synonyme d'une meilleure pratique, mais pas de questions sur ma main de toute façon
OriginalL'auteur user172902 | 2016-08-21
Vous devez vous connecter pour publier un commentaire.
La question ne doit pas être "puis-je utiliser la faiblesse de référence", mais plutôt "dois-je utiliser la faiblesse de la référence." Vous utilisez des références faibles pour éviter les forte des cycles de référence ou de garder une fermeture tenait à quelque chose après il peut avoir été éliminés. Mais ne l'ajoutez pas de références faibles parce que vous peut.
Dans le cas 1, vous probablement ne voulez utiliser
[weak self]
. Pourquoi? Parce que si le point de vue du contrôleur a été rejetée alors que l'autorisation a été en cours, avez-vous vraiment envie de garder une référence à une vue contrôleur qui a été rejeté? Probablement pas dans ce cas.Dans le cas 2, vous pourrait théoriquement utiliser
[weak self]
dans leanimation
bloc, mais pourquoi le feriez-vous? Il n'y a aucune raison de le faire. La faiblesse de référence est quelque chose que vous faites avec l'achèvement des gestionnaires et/ou à la fermeture des variables, mais pour un bloc d'animation il dispose d'aucune utilité, je ne voudrais pas le faire. Pour utiliserweak
ici suggère une incompréhension de la mémoire sémantique impliqués.Dans le cas 3, vous disposez de deux questions distinctes.
Dans le
didSelectItemAtIndexHandler
, qui devrait probablement utiliser[unowned self]
parce que l'objet propre de la fermeture est en se référant à lui-même.Il peut être une question discutable, car je ne vous vois pas réellement l'aide que
BTNavigationDropdownMenu
(peut-être que l'initialiseur est l'ajout de lui-même à la manette de navigation, mais ce n'est pas un initialiseur si donc, à mon humble avis).Mais comme un concept général, lorsqu'un objet a un gestionnaire de fermeture qui ne peut être appelée lorsque l'objet est toujours là, mais elle ne devrait pas, à elle seule, l'objet doit être conservé, il vous suffit d'utiliser
[unowned self]
.Dans le cadre plus large
checkUserLoggedIn
fermeture, la question est de savoir si c'est un gestionnaire d'achèvement. Si oui, vous devriez probablement utiliser[weak self]
, parce que cela pourrait être initié et être en cours d'exécution par le tempsself
est rejeté, et vous ne voulez pas avoircheckUserLoggedIn
de conserver une référence à une-vue-contrôleur qui a été rejeté. Mais vous ne voulez pas utiliser[unowned self]
parce que ce serait vous laisser pendre les pointeurs si il avait été sorti par le temps, la fermeture des pistes.En aparté, vous contemplez:
Que c'est un peu unswifty. Vous devez utiliser la
[weak self]
modèle au début de lacheckUserLoggedIn
fermeture. Si vous avez un exemple où vous êtes tentés d'utiliserweak var weakSelf = ...
, vous devez éditer votre question, y compris un exemple de cas où vous souhaitez utiliser le modèle. Mais ce n'est pas un de ces cas.Re les références faibles en
animation
fermetures offre pas l'utilité: Leanimation
fermeture fourni àanimateWithDuration
n'est pas un gestionnaire d'achèvement, qui est exécuté à plus tard (même si il y a un autrecompletion
la fermeture, mais une autre boule de cire au total). Il est appelé immédiatement, et l'animation est lancée, mais la fermeture n'est pas en gardant de fortes références àself
pour la durée de l'animation.Re réseau fermetures toujours besoin faible/propriétaire: Non, ce n'est certainement pas le cas. Par exemple, vous pourriez faire quelque chose dans cette fermeture que exécuter (par exemple, mise à jour de la bd locale concernant l'achèvement de la demande de réseau; enregistrer image téléchargée à cache; etc.). Utilisez uniquement la faiblesse de la si vous n'avez pas besoin/voulez le code dans la fermeture de garder la référence à l'objet (par exemple, vous êtes à la simple mise à jour de l'INTERFACE utilisateur, mais pas la mise à jour des caches ou des bases de données ou des structures de modèle). Ne vous contentez pas bêtement utiliser
weak
: Regardez ce qui est dans la fermeture et de décider si elle doit être (ou doit être) faible ou pas.Est-il vrai que si le VC n'est jamais rejeté, je n'ai pas besoin de préoccupation au sujet de la solidité de cycle de référence?
En mettant ce que j'ai appris, Pourriez-vous s'il vous plaît prendre un coup d'oeil à ma mise à jour avec les cas 4 et de la question à ce sujet.
OriginalL'auteur Rob