[Noob,Swift] Varibales Publiques

Procuste34Procuste34 Membre
juin 2015 modifié dans API UIKit #1

Salut à  tous ! Je suis en encore sur mon application qui fait des calcules , je me suis encore heurter à  un problème, cette fois ci beaucoup plus "noob" ;-)


 


J'ai fait un Slider, qui est proportionné ( par exemple , de 0 à  100, on va de 5 en 5, et de 100 à  500 on va de 10 en 10 )


 


Pour cela , j'ai fait une "boucle" if else if, qui, je pense est loin d'être la meilleur solution, mais bon ;)


 


J'ai fait cette boucle dans l'IBAction réliée au Slider.


A chaque else if , je modifie une variable , en l'occurence "newvalue"


 


Le problème, c'est que je veux m'en servir plus bas, mais hors de la boucle if else if ... Mais je veux m'en servir que dans l'IBAction réliée au Slider ! 


 


Je ne me suis pas arrêté la, j'ai essayer de mettre en public les classes d'haut dessus, l'IBAction elle même, et même essayer de créer une fonction public ( qui contiendrait ma boucle if, même si ce n'est pas une boucle ) dans l'IBAction , mais ce message d'erreur apparait : "Attribute "public" can be only used in non local scope".


 


Voila,voila, j'espère que vous aurez une réponse ... Et en tout cas, merci de m'avoir lu ;) A plus.


 


EDIT : Photo :


Réponses

  • CéroceCéroce Membre, Modérateur

    Une variable a une portée (en anglais "scope") limitée à  la méthode dans laquelle elle est a été déclarée.


    Si tu veux qu'elle soit accessible aux autre méthodes, il faut la déclarer en variable d'instance.


  • Procuste34Procuste34 Membre
    juin 2015 modifié #3


    Une variable a une portée (en anglais "scope") limitée à  la méthode dans laquelle elle est a été déclarée.


    Si tu veux qu'elle soit accessible aux autre méthodes, il faut la déclarer en variable d'instance.




    Ok merci ;)


    Juste, tu peux me donner un bref exemple ? ;P


  • PyrohPyroh Membre

    Je crois que le scope n'est pas le problème principal ici...

    Tu as vraiment des else/if de 0 à  500 ? Si oui va falloir reprendre les bases de l'algorithmique :

     



    var newValue: Float = 0
    if value <= 100 {
    newValue = value * 5
    } else {
    newValue = value * 10

    Mieux non ? 


     


    On déclare newValue en dehors du scope du if/else donc il en est accessible en dehors.


    Après je pense que tu comprends ce que le code fait. Sinon un passage par là  : Cours de base (y jeter un coup d'oeil ne ferait pas de mal quand même)


     


    Après pour ta fonction j'ai comme un doute, normalement la signature d'un @IBAction c'est sender: AnyObject mais c'est peut être différent sur iOS (bien que j'en doute)


  • Procuste34Procuste34 Membre
    juin 2015 modifié #5


    Je crois que le scope n'est pas le problème principal ici...

    Tu as vraiment des else/if de 0 à  500 ? Si oui va falloir reprendre les bases de l'algorithmique :

     



    var newValue: Float = 0
    if value <= 100 {
    newValue = value * 5
    } else {
    newValue = value * 10

    Mieux non ? 


     


    On déclare newValue en dehors du scope du if/else donc il en est accessible en dehors.


    Après je pense que tu comprends ce que le code fait. Sinon un passage par là  : Cours de base (y jeter un coup d'oeil ne ferait pas de mal quand même)


     


    Après pour ta fonction j'ai comme un doute, normalement la signature d'un @IBAction c'est sender: AnyObject mais c'est peut être différent sur iOS (bien que j'en doute)




    -Non, j'en ai "que" 60 ;)


    -Merci ! ;)


    -Oui, mais la c'est sur une WatchApp , et j'ai remarqué que c'est un peu différent d'iOS ouai ;)


  • AliGatorAliGator Membre, Modérateur

    Après pour ta fonction j'ai comme un doute, normalement la signature d'un @IBAction c'est sender: AnyObject mais c'est peut être différent sur iOS (bien que j'en doute)

    Sous UIKit, tu n'est pas obligé de mettre ni le sender ni le event.
    cf cette doc


    Sinon Procuste34 ça serait intéressant (effrayant ?) de voir ton code pour voir pourquoi tu fais tant de "if else" etc.
  • DrakenDraken Membre
    juin 2015 modifié #7

    Pourquoi ne pas utiliser un tableau à  la place de cette interminable série de tests ?


    a



    let listeValeurs = [0, 5, 10, 15, les autres valeurs .. ]

    let newValue = listeValeurs[value]
    montantLabel.setText(String(newValeur))


    a


    EDIT : Oups, je n'avais pas lu la description de ton problème, juste regardé ton code. La solution de Pyroh est bien meilleure.


    aa



    // Exemple de variable publique
    // accessible à  toutes les fonctions de la class MaClasse

    class MaClasse {
    var newValue = 0 // Là  c'est une variable publique dans la classe

    func fonction1() {
    // On peut modifier newValue ici
    newValue = 12
    }

    func fonction2() {
    // On peut utiliser newValue ici
    let calcul = newValue * 5
    }
    }




     


     


    A chaque else if , je modifie une variable , en l'occurence "newvalue"

     


    La norme est d'utiliser des majuscules dans les noms de variables, pour les rendre plus lisibles.


    a




    newvalue = 12 // PAS BIEN
    newValue = 12 // BIEN


  • AliGatorAliGator Membre, Modérateur

    Je crois que le scope n'est pas le problème principal ici...
    Tu as vraiment des else/if de 0 à  500 ? Si oui va falloir reprendre les bases de l'algorithmique :
     


    var newValue: Float = 0
    if value <= 100 {
    newValue = value * 5
    } else {
    newValue = value * 10
    Mieux non ?

    Quitte à  utiliser les idiomes de Swift :
    - je te conseille un "let" plutôt qu'un "var" (normalement les dernières versions du compilateur savent détecter que la variable est initialisée avant d'être utilisée même si elle est initialisée à  des valeurs différentes selon la branche du if ou du switch)
    - je ferais plutôt un "switch" en utilisant le pattern matching avec des "Range", avec "case 0...100" etc.

    Ce qui donnerait par exemple :

    let newValue: Float
    switch value {
    case 0...100:
    newValue = 5
    case 101...500:
    newValue = 10
    default:
    newValue = 1
    }
    print("newValue = \(newValue)")
    Ou même si tu veux des cas plus avancés :

    let newValue: Float
    switch value {
    case 0...100:
    newValue = 5
    case 101...500:
    newValue = 10
    case let x where x>500:
    newValue = 100
    case let x where x<0:
    newValue = 0
    }
    print("newValue = \(newValue)")


  • Sous UIKit, tu n'est pas obligé de mettre ni le sender ni le event.
    cf cette doc



    Sinon Procuste34 ça serait intéressant (effrayant ?) de voir ton code pour voir pourquoi tu fais tant de "if else" etc.




    Bah je fais un Slider qui de 0 à  100 va de 5 en 5 , de 100 à  500  va de 10 de 10 , et c'est une app pour Watch ;)

  • Merci pour toutes vos réponses ; malheuresement , je ne peux pas testé tout de suite, la Watch Simulator ne marche plus :/ Vive que je reçoive ma watch 


  • AliGatorAliGator Membre, Modérateur


    Bah je fais un Slider qui de 0 à  100 va de 5 en 5 , de 100 à  500 va de 10 de 10 , et c'est une app pour Watch ;)

    c'est pas du code ça. ça ne nous dis pas si tu s codé ça commun un sagouin ou proprement, avec 60 if/else comme un porc ou avec du pattern matching ou un algo plus posé.

  • Quitte à  utiliser les idiomes de Swift :- je te conseille un "let" plutôt qu'un "var" (normalement les dernières versions du compilateur savent détecter que la variable est initialisée avant d'être utilisée même si elle est initialisée à  des valeurs différentes selon la branche du if ou du switch)- je ferais plutôt un "switch" en utilisant le pattern matching avec des "Range", avec "case 0...100" etc.Ce qui donnerait par exemple :

    let newValue: Floatswitch value {case 0...100:    newValue = 5case 101...500:    newValue = 10default:    newValue = 1}print("newValue = \(newValue)")
    Ou même si tu veux des cas plus avancés :
    let newValue: Floatswitch value {case 0...100:    newValue = 5case 101...500:    newValue = 10case let x where x>500:    newValue = 100case let x where x<0:    newValue = 0}print("newValue = \(newValue)")
    Sur ce point nous sommes entièrement d'accord mais j'ai voulu conserver quelque chose de vraiment simple et compréhensible d'où l'omission du switch.

    Pour le let au lieu de var je suis moins d'accord. Dans ce cas c'est vrai y'a pas photo mais comme il a dit qu'il voulait encore faire quelque chose plus tard dans le code avec newValue il me paraissait plus sage de le laisser mutable histoire de pas l'embrouiller.
  • AliGatorAliGator Membre, Modérateur
    Je ne suis pas d'accord. Il faut toujours mieux déclarer avec let et ensuite changer en var seulement si c'est vraiment nécessaire (ça force à  se poser la question de savoir si c'est une bonne idée de la rendre mutable) que commencer par "var" et du coup ne jamais penser à  transformer en "let" et risquer ainsi de perdre tous les avantages du let (protection contre les erreurs de mutation non souhaitée, thread-safety, optimisations du compilateur, etc etc) que ne permettent pas forcément le "var".


    Tu peux être sur que si tu prends l'habitude de commencer par mettre "var" en te disant "on verra après si on le convertit en "let" plus tard" que ce plus tard n'arrivera jamais car tu vas oublier et tu ne repasseras jamais sur tous tes var pour les transformer en let. Du coup ça risque de devenir une mauvaise habitude et une mauvaise pratique.


  • Je ne suis pas d'accord. Il faut toujours mieux déclarer avec let et ensuite changer en var seulement si c'est vraiment nécessaire (ça force à  se poser la question de savoir si c'est une bonne idée de la rendre mutable) que commencer par "var" et du coup ne jamais penser à  transformer en "let" et risquer ainsi de perdre tous les avantages du let (protection contre les erreurs de mutation non souhaitée, thread-safety, optimisations du compilateur, etc etc) que ne permettent pas forcément le "var".


    Tu peux être sur que si tu prends l'habitude de commencer par mettre "var" en te disant "on verra après si on le convertit en "let" plus tard" que ce plus tard n'arrivera jamais car tu vas oublier et tu ne repasseras jamais sur tous tes var pour les transformer en let. Du coup ça risque de devenir une mauvaise habitude et une mauvaise pratique.




    Ce en quoi tu as totalement raison et c'est d'ailleurs comme ça que je travaille. Xcode 7 te tape même sur doigts si tu ne le fais pas. C'est vrai aussi que même dans un but didactique j'aurai du mettre let.

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