Mise à  nil d'une variable (Swift)

Lightman18Lightman18 Membre
mars 2015 modifié dans API UIKit #1

Bonsoir,


 


Aujourd'hui je rencontre un problème de base qui m'empêche de continuer mon projet. Personne n'a trouvé la soluce pour l'instant. Alors je le mets ici.


Pour l'illustrer, je l'ai simplifié au max : nouveau projet Xcode Swift, et voilà  l'intégralité de mon code :


 


Mots clés:

Réponses

  • LouLou Membre

    Regarde un tuto sur les variables optional en swift (ou alors tape l'erreur dans google et tu auras déjà  des discussions là -dessus). Avec Swift, si la variable peut être "nil", il faut que tu le dises avec un "?". De cette façon, si un moment dans ton code, la variable en question est nil, ça ne crash pas, ça ignore le code en douceur.


  • AliGatorAliGator Membre, Modérateur
    mars 2015 modifié #3
    var unJoueur = Joueur() // La variable unJoueur est inféré comme étant de type Joueur (et non Joueur?)
    // Du coup tu ne peux pas la passer à  nil plus tard, car le type Joueur n'est pas optional.

    var unAutreJoueur: Joueur? = Joueur() // La variable est explicitement de type Joueur? (autrement dit Optional<Joueur>)
    // Etant de type optional, cette variable pourra donc être nil plus tard dans son cycle de vie
    unAutreJoeur = nil // Du coup c'est OK.
  • Lightman18Lightman18 Membre
    mars 2015 modifié #4

    Je n'ai pas trouvé sur le net avec le fameux message, en tout cas pas de réponse à  ça.


    Maintenant, je te remercie de tes indications Lou mais je ne suis pas sûr qu'on parle de la même chose. Ce que je veux faire, c'est affecter nil à  mon pointeur sur objet pour couper la strong référence et lui permettre d'être désalloué. pas d'optionel là  dedans.


  • @AliGator : Hum... ça veut dire que la plupart des objets créés de manière simple ne sont pas destructibles (libérables) puisque leur référence ne peut pas être supprimée ? Bon je vais faire des tests.


     


    Il va falloir que je bosse encore la gestion mémoire en Swift moi. Ce n'est pas encore clair...


  • DrakenDraken Membre
    mars 2015 modifié #6

    Intéressant. Je me serais fait avoir aussi. Merci de ce retour d'expérience, Ligthman18.


     


    Tu devrais renommer le topic avec un titre comme "mise à  nil d'une variable (Swift)" 

  • Lightman18Lightman18 Membre
    mars 2015 modifié #7

    Pourquoi mise à  nil d'une variable ? Cette "variable" n'est elle pas en fait un pointeur ? Et comme elle est déclarée en var, ne pourrait-on pas lui affecter 0 ?


     


    Comment procède t'on dans le cas général ? on crée tous les objets de la façon suivante ?



    var unObjet: NomDeLaClasse? = NonDeLaClasse()

    C'est différent des exemples que j'ai vu.


     


    Merci des indications déjà  données jusque là .


  • DrakenDraken Membre
    mars 2015 modifié #8

    La notion de pointeur n'existe pas en Swift.


    Une variable objet doit forcément contenir un objet, ( et nil pour les variables de type optional). 0 est une valeur purement numérique, et non un objet.


    .


    Je t'ai suggéré de changer le titre du topic car c'est utile de savoir qu'on ne peut pas mettre nil dans toutes les variables objets en Swift. D'autres débutants seront certainement contents de trouver une explication sur le sujet en parcourant les titres des topics.

  • Oups. La question qui débute mon poste précédent ne portait pas sur le titre du topic. Pas de pb avec ça.


    Je te remercie pour tes indications. Je comprends un peu mieux. A l'avenir, je vais voir comment je fais : mettre des optionals de partout, ou ne pas gérer la fin de vie des objets. On verra comment ça se passe.


  • AliGatorAliGator Membre, Modérateur

    @AliGator : Hum... ça veut dire que la plupart des objets créés de manière simple ne sont pas destructibles (libérables) puisque leur référence ne peut pas être supprimée ? Bon je vais faire des tests.

    Je n'ai jamais dit ça. Et non ce n'est pas le cas, bien sûr que ces objets seront détruits, et encore heureux.

    Les objets créés directement avec Joueur() sont tout à  fait destructibles, comme en ObjC, ils seront détruits quand aucune variable/propriété n'y fera plus référence.
    Si tu écris "var unJoueur = Joueur()" le joueur ainsi créé va rester en vie jusqu'à  ce que la variable unJoueur elle-même sorte du scope où elle a été déclarée. Si c'est une variable locale à  l'intérieur d'une fonction, la variable d'existera plus quand tu sortiras de la fonction. Si c'est une propriété, elle n'existera plus quand l'objet qui la contient sera lui-même détruit, etc.


    Maintenant ça n'enlève rien au fait que si tu déclares une propriété sur un objet, si tu veux que cette propriété, pendant la durée de vie de l'objet dans laquelle la propriété est déclarée puisse repasser à  nil, alors il faut la déclarer Optional évidemment. Car tu veux que, pendant que la propriété existe encore (car son objet qui la déclare existe encore), faire pointer cette variable sur nil, lui affecter nil, donc il faut qu'elle soit Optional.
    Si tu ne la déclares pas Optional, tu ne pourras pas lui affecter nil, mais ça n'empêche pas que quand l'objet parent sera détruit il ne retiendra plus ton Joueur et ce Joueur sera détruit à  son tour (si personne d'autre ne le retiens naturellement), comme en Objective-C en fait.


    Ce que je veux dire c'est que ce n'est pas la peine de "tout déclarer en Optional" juste dans l'idée que "si tu ne le fais pas tes objets ne seront pas libérés"... car Optional ou pas, ils sont bien libérés (du moment que tu ne fais pas de strong reference cycle évidemment " là  encore comme en ObjC)


    ---

    La seule question à  te poser c'est "est-ce que cette propriété elle peut être "nil" pendant la durée de vie de l'objet parent qui la contient ?"
    - Si oui, autrement dit si tu veux pouvoir écrire "unJoueur = nil" et des "if unJoueur != nil { ... }" etc., et que ça a du sens pour toi (parce que ça a du sens dans ton jeu par exemple, à  toi de voir) alors il faut la déclarer Optional pour indiquer ce fait que c'est tout à  fait possible que unJoueur soit nil. Le fait de le déclarer Optional va t'obliger à  chaque fois que tu veux utiliser ta propriété unJoueur à  tester si elle est nil ou pas avant de l'utiliser (explicitement avec des "if unJoueur != nil {}" ou avec des "if let" ou du Optional Chaining, mais au final tout ça c'est pareil), et c'est le but car ça va te forcer à  chaque utilisation à  penser au cas particulier où unJoueur peut être nil et agir en conséquence au lieu de risquer d'oublier de traiter le cas particulier.
    - Par contre si ça n'a pas de sens que ta variable unJoueur puisse être nil pendant la durée de vie de ton objet, par exemple si c'est une propriété de ta classe Jeu et qu'un Jeu ne peut pas se concevoir s'il n'y a pas un Joueur pour y jouer et donc que ça n'a pas de sens que unJoueur soit nil, alors il n'y a pas de raison de le mettre en Optional. Car il n'y a pas de raison que tu aies à  écrire "unJoueur = nil" dans ton code. Ca n'empêchera pas ton joueur stocké dans unJoueur d'être supprimé quand l'objet Jeu lui-même sera supprimé, tout comme en ObjC une variable strong est quand même relâchée quand l'objet qui contient la propriété est lui-même détruit...
  • OK merci pour ces longues explications, utiles et claires.


    (tu devrais faire des tutos ;-)


  • Juste une petite précision sur la sémantique de nil.


     


    Nil en Objective C est un pointeur vers un objet non existant.


    En swift nil n'est pas un pointeur, c'est une absence de valeur pour un certain type. Tous les type optionnels peuvent être assignés à  nil. 


Connectez-vous ou Inscrivez-vous pour répondre.