Autocompletion avec Swift

yoannyoann Membre
mai 2015 modifié dans Objective-C, Swift, C, C++ #1

Bonjour tout le monde,


 


Je suis en train de faire une appli test sur iOS 8 et je me suis dis que j'allais tester en Swift vu que tout le monde dit que c'est mature.


 


Et forcément, j'ai des truc incohérent.


 


Entre autre sur l'autocompletion, je comprends pas.


 


Je commence à  tapper :



NSNotificationCenter.post

Puis je fais esc pour avoir l'autocompletion, le popup me propose bien les trois méthodes même si la présentation est à  chier.


 


«1

Réponses

  • PyrohPyroh Membre
    mai 2015 modifié #2

    Parce ça n'est pas une méthode de classe...

     

    ça, ça fonctionnera mieux :



    NSNotificationCenter.defaultCenter().postNotification(notification: NSNotification)

    De manière générale, avec Swift, quand tu vois self dans l'auto-complétion c'est que tu essaie d'appeller une méthode d'instance comme une méthode de classe.


  • yoannyoann Membre

    En effet, erreur de ma part.


     


    Enfin du coup la question reste. Pourquoi cet abruti me propose à  l'autocompletion des éléments qui n'existent pas ?


  • DrakenDraken Membre

    T'as essayé sans le traiter d'abruti, ni d'andouille ?

  • PyrohPyroh Membre

    Parce que si le langage et le compilo sont peut-être matures les outils de dev ont encore besoin d'un peu de temps.


     


    Xcode est encore un peu con-con quand on lui parle de Swift. Au moins il ne crash plus toutes les 18 secondes...


  • CéroceCéroce Membre, Modérateur

    Je suis en train de faire une appli test sur iOS 8 et je me suis dis que j'allais tester en Swift vu que tout le monde dit que c'est mature.

    Je n'irais pas jusqu'à  dire que c'est mature, mais que c'est enfin utilisable. J'ai fait un petit essai avec Scene Kit, et tout a tourné comme sur des roulettes, avec une syntaxe agréable, et des messages d'erreur compréhensibles.
  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #7
    Ce qu'il te propose est tout à  fait valable.

    En Swift (comme dans d'autres langages qui supportent cette feature), une méthode d'instance est aussi une méthode de classe qui prend self en argument et retourne la méthode d'instance associée (Currying).
    ça peut s'avérer très pratique par exemple pour passer en paramètre une méthode d'instance qui sera appliquée plus tard mais tu ne sais pas encore sur quelle instance (en passant la méthode de classe currified sous forme de closure en paramètre) ; très adapté pour la programmation fonctionnelle par exemple.

    ça te permet de faire des choses qu'en Objective-C tu ferais en passant un @selector et en faisant ensuite une NSInvocation ou un performSelector: sur l'instance... sauf qu'en utilisant la currification de la méthode d'instance comme étant une application (au sens mathématique) d'une méthode de classe sur self, tu as en bonus la vérification syntaxique qui est toujours présente et les contrôles du compilateur qui te permettent de garder une cohérence des domaines d'application de tes méthodes.
  • yoannyoann Membre


    Ce qu'il te propose est tout à  fait valable.


    En Swift (comme dans d'autres langages qui supportent cette feature), une méthode d'instance est aussi une méthode de classe qui prend self en argument et retourne la méthode d'instance associée (Currying).

    ça peut s'avérer très pratique par exemple pour passer en paramètre une méthode d'instance qui sera appliquée plus tard mais tu ne sais pas encore sur quelle instance (en passant la méthode de classe currified sous forme de closure en cours a ramette) très adapté pour la programmation fonctionnelle par exemple.


    ça te permet de faire des choses qu'en Objective-C tu ferais en passant un @selector et en faisant ensuite une NSInvocation ou un performSelector: sur l'instance... sauf qu'en utilisant la currification de la méthode d'instance comme étant une application (au sens mathématique) d'une méthode de classe sur self, tu as en bonus la vérification syntaxique qui est toujours présente et les contrôles du compilateur qui te permettent de garder une cohérence des domaines d'application de tes méthodes.




     


    Tu aurais un exemple de code Swift pour ça ?


     


    Je ne vois pas trop à  quel moment tu spécifie la version de la méthode qui t'intéresse (l'autocomplétion ne semble pas prendre en compte les arguments).

  • DrakenDraken Membre


    ça te permet de faire des choses qu'en Objective-C tu ferais en passant un @selector et en faisant ensuite une NSInvocation ou un performSelector: sur l'instance... 




    Mais non, voyons. Pour faire une invocation il faut dessiner une croix à  5 branches sur le sol, et prononcer  le nom de l'entité à  invoquer. Techniquement la croix n'est pas strictement nécessaire, c'est un symbole d'ordre servant à  emprisonner l'entité pour éviter qu'elle ne démembre l'invocateur avant de le manger.

  • AliGatorAliGator Membre, Modérateur
    J'ai pas d'exemple du monde réel comme ça en tête (je reviens de vacances, j'ai pas codé depuis un bail je suis pas inspiré ^^), mais en voici un imaginaire :

    class Animal {
    var name: String
    init(name: String) {
    self.name = name
    }

    func humanAge(realAge: Int) -> String {
    return "When \(name) is \(realAge), it's human age is \(realAge)."
    }

    func clipName(maxLength: Int) -> String {
    return prefix(name, maxLength)
    }
    }

    class Dog : Animal {
    override func humanAge(realAge: Int) -> String {
    return "When \(name) is \(realAge), as a Dog, it's human age is \(realAge*7)."
    }
    }

    class Cat : Animal {
    override func humanAge(realAge: Int) -> String {
    return "When \(name) is \(realAge), as a Cat, it's human age is \(realAge*6)."
    }
    }

    let a1 = Cat(name: "Felix")
    let a2 = Cat(name: "Garfield")
    let a3 = Dog(name: "Rantanplan")
    let animals = [a1,a2,a3]

    func listAges(f: Animal->Int->String) {
    let ageFunctions = animals.map(f)
    for age in 0...5 {
    for f in ageFunctions { println( f(age) ) }
    }
    }

    listAges(Animal.humanAge) // Applique la méthode d'instance humanAge à  chaque animal
    listAges(Animal.clipName)
    Je ne dis pas que mon exemple est utile (j'ai pas été très inspiré), je dis juste que c'est un des concepts existant en programmation fonctionnelle que Swift te permet d'utiliser, en utilisant le Currying.
    (D'ailleurs tu m'aurais demandé un exemple d'utilisation de performSelector en ObjC je crois que j'aurais pas été beaucoup plus inspiré non plus)

    Si tu as fait un peu mumuse avec le Runtime d'Objective-C, tu sais déjà  certainement qu'en Objective-C, les classes sont des instances de méta-classes, et que les "méthodes de classe" d'une classe ne sont en fait que des méthodes d'instances de la méta-classe. Bah là  c'est un peu pareil. Les méthodes d'instance d'une classe Swift ne sont que des méthodes de classe qui prennent une instance en paramètre (et retourne une méthode à  appliquer pour avoir le résultat sur ladite instance).

    Après je ne suis pas assez à  l'aise avec le Functional Programming et ses bonnes pratiques pour savoir te dire quand c'est utile et quand c'est + conseillé, en FP, d'utiliser ce genre de chose (méthode fonctionnelle sur une instance, type "fonctor" ou "applicateur", plutôt que de passer par de l'itératif ou autre), mais bon, tout ce que je peux te dire c'est que les faits sont là , le concept existe en FP et en Swift, c'est un fait.
  • yoannyoann Membre

    Merci pour l'exemple. Je vois bien l'idée derrière, comme je dis à  mes élèves, c'est du pointeur de fonction amélioré.


     


    Par contre j'ai un soucis dans ce que m'auto complète Xcode si c'est vraiment lié à  ça, c'est que ça ne semble pas spécialement intelligent ni malléable dans le sens où je ne capte toujours pas à  quel moment tu spécifie la version de la méthode que tu souhaite utilisé.


     


    Si je reprend l'exemple des NSNotifications nous avons :



    NSNotificationCenter.defaultCenter().postNotificationName(<#aName: String#>, object: <#AnyObject?#>)
    NSNotificationCenter.defaultCenter().postNotificationName(<#aName: String#>, object: <#AnyObject?#>, userInfo: <#[NSObject : AnyObject]?#>)

    Or lorsque l'on utilise le currying avec Swift, il n'affiche que :



    NSNotificationCenter.postNotificationName(<#NSNotificationCenter#>)

    Du coup je ne comprends pas à  quel moment on est capable de lui dire quel est réellement la méthode que je cherche.


     


    Car "postNotificationName" n'existe pas du tout en réalité. C'est soit postNotificationName:object:, soit postNotificationName:object:userInfo:


     


    Que ce soit du Swift ou de l'ObjC, il y a besoin du nom de méthode complet pour savoir quel implémentation utiliser.


     


    La détection ne peu se faire au nombre ni au type d'arguments mais bien au nom complet de la méthode.


     


    Tous les exemples de currying que j'ai vu ne semblent utiliser qu'un seul argument.


     


    Du coup je comprends pas franchement le cas d'usage si on limite ça à  un seul argument.


  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #12
    La méthode suivante :
    NSNotificationCenter.postNotificationName(<#NSNotificationCenter#>)
    Est une méthode (de classe) qui, une fois que tu lui as passé une instance de NSNotificationCenter, te retourne une méthode (équivalent de la méthode d'instance du NSNotificationCenter en question) prenant une NSNotification en paramètre, et l'envoie. C'est donc la version currified de la méthode d'instance suivante :
    NSNotificationCenter.defaultCenter().postNotification(<#notification: NSNotification#>)
    Donc il n'y a aucun souci là  dessus, cette méthode qu'il te propose est valide, et ne correspond à  aucune des 2 méthodes que tu as cité, mais à  une 3ème dont tu avais sans doute oublié l'existence, qui est postNotification() tout court.

    Si tu veux utiliser une des 2 méthodes que tu as cité, les 2 méthodes s'appellent "postNotificationName()" (et pas juste "postNotification()"). Et ces 2 méthodes se différencient juste par la liste de leurs arguments. Et chez moi elles sont bien proposées lors de l'auto-complétion sans soucis (Xcode 6.3.1), donc tout fonctionne comme attendu :
  • yoannyoann Membre


    La méthode suivante :



    NSNotificationCenter.postNotificationName(<#NSNotificationCenter#>)

    Est une méthode (de classe) qui, une fois que tu lui as passé une instance de NSNotificationCenter, te retourne une méthode (équivalent de la méthode d'instance du NSNotificationCenter en question) prenant une NSNotification en paramètre, et l'envoie. C'est donc la version currified de la méthode d'instance suivante :

    NSNotificationCenter.defaultCenter().postNotification(<#notification: NSNotification#>)

    Donc il n'y a aucun souci là  dessus, cette méthode qu'il te propose est valide, et ne correspond à  aucune des 2 méthodes que tu as cité, mais à  une 3ème dont tu avais sans doute oublié l'existence, qui est postNotification() tout court.


     


    Relis le nom des méthodes. J'espère que postNotificationName ne renvois pas sur postNotification sinon on a un gros soucis ^^


     


     




    Si tu veux utiliser une des 2 méthodes que tu as cité, les 2 méthodes s'appellent "postNotificationName()" (et pas juste "postNotification()"). Et ces 2 méthodes se différencient juste par la liste de leurs arguments. Et chez moi elles sont bien proposées lors de l'auto-complétion sans soucis (Xcode 6.3.1), donc tout fonctionne comme attendu :


    attachicon.gifNotificationCenter-Completion.png


    Il me propose bien 2 méthodes de classe nommées postNotificationName(), prenant une instance de NSNotificationCenter en paramètre pour obtenir en retour la méthode d'instance voulue, et selon ensuite comment tu vas utiliser cette méthode d'instance, le compilateur va faire du backtracking lors de la compilation pour savoir, en fonction des arguments que tu lui passeras plus tard quand tu vas utiliser cette méthode, à  quelle variante finalement tu pensais (puisque tu fais du tapage implicite, c'est pas backtracking à  la compilation que swiftc détermine le type explicite pour le deviner tout seul)

     




     


     


    Tu es en train de me dire que pour savoir quel méthode d'instance retourner ici 



    NSNotificationCenter.postNotificationName(<#NSNotificationCenter#>)

    il va, à  la compilation, essayer de deviner (dans l'intégralité du code disponible et des potentiels bundle qui ne sont pas encore écris) de quel méthode je parle ?


     


    On marche sur la tête là  non ?

  • AliGatorAliGator Membre, Modérateur
    mai 2015 modifié #14

    Relis le nom des méthodes. J'espère que postNotificationName ne renvois pas sur postNotification sinon on a un gros soucis ^^

    Et toi, relis bien mon message, j'ai jamais dit ça. "postNotification" renvoie sur "postNotification(<#aNotification#>)" et "postNotificationName" renvoie sur "postNotificationName(<#String#>, <#object: AnyObject?#>)" ou sur "postNotificationName(<#String#>, <#object: AnyObject?#>, <#userInfo: [NSObject:AnyObject]?#>)" selon le contexte.

    C'est bien ce que j'ai écrit plus haut et ce que ma capture d'écran confirme.

     

    Tu es en train de me dire que pour savoir quel méthode d'instance retourner ici

    NSNotificationCenter.postNotificationName(<#NSNotificationCenter#>)
    il va, à  la compilation, essayer de deviner (dans l'intégralité du code disponible et des potentiels bundle qui ne sont pas encore écris) de quel méthode je parle ?

    On marche sur la tête là  non ?

    Au contraire c'est tout ce qu'il y a de plus logique et c'est le principe du backtracking. J'aurais peut-être pas dû employer le terme "deviner" mais plutôt "déduire".

    Et on est loin de marcher sur la tête, bien au contraire. C'est le principe même du typage implicite (et ça, ça n'a rien à  voir avec le currying et avec le fait que les méthodes d'instance sont des méthodes de classe prenant l'instance en paramètre). C'est le même principe qui fait que quand tu appelles une fonction surchargée, Swift sait déduire quelle version de la fonction il doit appeler en déduisant via le type des paramètres (et via du backtracking si le type des paramètres n'est pas lui-même implicite).
    D'ailleurs, j'espère que ça ça ne te surprend pas non plus, c'est un peu la base des langages de programmation moderne d'avoir un compilateur suffisamment intelligent pour déduire les surcharges à  utiliser selon le contexte...
  • AliGatorAliGator Membre, Modérateur

    Merci pour l'exemple. Je vois bien l'idée derrière, comme je dis à  mes élèves, c'est du pointeur de fonction amélioré.

    Je n'avais pas relevé tout à  l'heure, mais tu me parais bien simpliste à  expliquer les choses comme ça... C'est bien plus que ça, car c'est typé, et en plus c'est aussi attaché à  un type, qu'il soit value-type ou reference-type (et si c'est un reference-type et que ça supporte l'héritage, cela suppose donc une résolution de quel type est déduit, et pourtant c'est résolu certes avec une vtable (comme en C++) mais aussi avant à  moitié à  la compilation (par la déduction du backtracking qui limite les possibilités et réduit la vtable en conséquence pour limiter les indirections).
  • yoannyoann Membre


    Je n'avais pas relevé tout à  l'heure, mais tu me parais bien simpliste à  expliquer les choses comme ça... C'est bien plus que ça, car c'est typé, et en plus c'est aussi attaché à  un type, qu'il soit value-type ou reference-type (et si c'est un reference-type et que ça supporte l'héritage, cela suppose donc une résolution de quel type est déduit, et pourtant c'est résolu certes avec une vtable (comme en C++) mais aussi avant à  moitié à  la compilation (par la déduction du backtracking qui limite les possibilités et réduit la vtable en conséquence pour limiter les indirections).




     


    Si tu explique cela à  une classe, tu les perd à  "typé" pour info ;-)

  • yoannyoann Membre


    Et toi, relis bien mon message, j'ai jamais dit ça. "postNotification" renvoie sur "postNotification(<#aNotification#>)" et "postNotificationName" renvoie sur "postNotificationName(<#String#>, <#object: AnyObject?#>)" ou sur "postNotificationName(<#String#>, <#object: AnyObject?#>, <#userInfo: [NSObject:AnyObject]?#>)" selon le contexte.


    C'est bien ce que j'ai écrit plus haut et ce que ma capture d'écran confirme.




     


     


    On doit pas lire le même forum :


     


    hum.png 54.7K
  • AliGatorAliGator Membre, Modérateur
    C'était pour voir si tu suivais.
  • yoannyoann Membre


    Au contraire c'est tout ce qu'il y a de plus logique et c'est le principe du backtracking. J'aurais peut-être pas dû employer le terme "deviner" mais plutôt "déduire".


    Et on est loin de marcher sur la tête, bien au contraire. C'est le principe même du typage implicite (et ça, ça n'a rien à  voir avec le currying et avec le fait que les méthodes d'instance sont des méthodes de classe prenant l'instance en paramètre). C'est le même principe qui fait que quand tu appelles une fonction surchargée, Swift sait déduire quelle version de la fonction il doit appeler en déduisant via le type des paramètres (et via du backtracking si le type des paramètres n'est pas lui-même implicite).

    D'ailleurs, j'espère que ça ça ne te surprend pas non plus, c'est un peu la base des langages de programmation moderne d'avoir un compilateur suffisamment intelligent pour déduire les surcharges à  utiliser selon le contexte...




     


    Quand à  ce point, c'est l'aberration moderne que je critique depuis le début sur Swift.


     


    La résolution statique est une connerie pure et dure. On avait un monde d'avance avec la résolution dynamique et l'ouverture que cela permet, et on est entrain de le perdre.


     


    Mais du coup j'ai ma réponse. Cette anomalie du langage est à  classer dans les conneries qui font croire que le langage est mieux alors que l'avantage présenté est carrément minoritaire par rapport aux inconvénients qu'il apporte.

  • AliGatorAliGator Membre, Modérateur


    Si tu explique cela à  une classe, tu les perd à  "typé" pour info ;-)

    et toi tu les perds à  "pointeur de fonctions" ;-)
  • AliGatorAliGator Membre, Modérateur

    Quand à  ce point, c'est l'aberration moderne que je critique depuis le début sur Swift.
     
    La résolution statique est une connerie pure et dure. On avait un monde d'avance avec la résolution dynamique et l'ouverture que cela permet, et on est entrain de le perdre.
     
    Mais du coup j'ai ma réponse. Cette anomalie du langage est à  classer dans les conneries qui font croire que le langage est mieux alors que l'avantage présenté est carrément minoritaire par rapport aux inconvénients qu'il apporte.

    La résolution n'est pas purement statique (j'ai bien indiqué qu'il restait une résolution dynamique plus haut).

    Et j'ai toujours j'ai du mal à  comprendre pourquoi tu parles d'anomalie du langage. Le langage a été pensé pour être un langage type-safe, donc c'est normal qu'il offre ce genre de fonctionnalités, qui sont entre autres sa force, permettant d'assurer le typage de bout en bout et d'avoir des choses comme des Array typés (generics) permettant entre autres au passage de ne pas perdre tout l'avantage de l'inférence du type des variables et des fonctions (fini les déclarations imbattables de variables de type block grace à  l'inférence de type par exemple, qui n'est possible que grace à  ce genre de chose comme le backtracking).

    Après, si t'aimes pas et veut jouer ton puriste "je préfère avoir la main sur tout et pouvoir faire n'importe quoi si ça me chante y compris appeler des méthodes sur des objets qui n'y répondent possiblement pas sans que le compilateur me gueule dessus car je préfère que ça crash au runtime", bah rien ne t'interdit d'utiliser un autre langage, genre rester à  l'Objective-C ou faire de l'Objective-C++. Ou encore d'utiliser les possibilités dynamiques de Swift " même si elles ne sont pas mises en avant car Swift n'a pas pour vocation d'inviter à  ça préférant le type-safety, le dynamic runtime et les possibilités de message forwarding d'ObjC sont toujours disponibles en Swift (genre "myObject.performSelector("someMethod", withObject: foo)") si ça t'amuse et que tu tiens tant que ça.
    Mais Swift a été pensé pour être type-safe " contrairement à  ObjC où on pouvait faire n'importe quoi et finir par écrire du code qui ne plantait qu'au runtime sans que le compilateur ne nous prévienne avant qu'il y avait une incohérence dans notre code " donc dans ce cadre, il répond parfaitement à  ce pour quoi il a été pensé. Si t'aimes pas c'est ton droit, mais chaque langage a son rôle et est prévu pour être utilisé en tant que tel.

    On pourrait aussi dire que le C c'est nul car ça ne permet pas de faire de l'objet, alors que toi tu dirais c'est bien car tu as le contrôle sur tout, y compris les pointeurs et la possibilité de manipuler la mémoire au plus bas niveau, tandis que d'autres cherchent un langage de plus haut niveau pour éviter de faire n'importe quoi avec la mémoire, chacun utilise le langage qui lui correspond le mieux (et encore, en Swift rien ne t'empêche de faire du dynamic message forwarding, de l'indirection, ou même manipuler la mémoire directement via les UnsafeMutablePointer<T>, etc... donc tu as toute latitude de faire tout ça quand même, donc je vois mal en quoicela te limite à  la résolution statique et en quoi tu aurais perdu tout cela, c'est encore tout à  fait possible)
  • yoannyoann Membre

    Tu peux faire de l'objet en C ^^


     


    Et sinon je critique Swift car je te rappel que je viens du dev OS X à  la base.


     


    Que sur OS X on a toujours pris l'habitude de faire des framework et des système de plugin. Et que ce qui est clairement monnaie courante sur OS X est une plaie en Swift : la résolution dynamique de méthode.


     


    Tout OS X fonctionne avec des plugins. Ouvre n'importe quelle application un peu grosse et tu verra que c'est prévu en plugin.


     


    Analyse n'importe quelle application un peu grosse et tu verra que ça utilise la résolution dynamique de méthode à  outrance.


     


    Analyse n'importe quelle application avec un look sympa sur OS X et tu verra que tu as besoin de la résolution dynamique.


     


    Analyse n'importe quelle application touchant au Finder sur OS X et tu verra que tu as besoin de la résolution dynamique.


     


    Même sur mes applications simple comme ma suite Admin Tools j'utilise de la résolution dynamique et des plugins pour être le plus malléable possible à  l'avenir (et ça m'a déjà  servis).


     


    Alors certes, sur des petites applications comme iOS, tu t'en fou, c'est des jouets. Quand tu es sur des applications qui te font sérieusement regretter le temps où Xcode pouvait faire de la compilation distribué et du hot fixe (des truc perdu lors du passage de gcc à  llvm), bah tu pleure en voyant Swift.


  • yoannyoann Membre

    C'est pas question de faire le crack en voulant tout contrôler.


     


    C'est question d'arrêter les conneries d'environnement hyper contrôlé qui n'est pas gênant sur un gadget comme iOS quand il est question d'OS X, histoire de conserver un écosystème riche.


  • AliGatorAliGator Membre, Modérateur

    Tu peux faire de l'objet en C ^^

    Et tu peux aussi faire de la gestion mémoire bas niveau et du dispatch dynamique en Swift.
    C'est justement exprès que j'ai pris cet exemple là  (et tu es tombé dedans les pieds joints, merci ^^)

    Analyse n'importe quelle application avec un look sympa sur OS X et tu verra que tu as besoin de la résolution dynamique.
     
    Analyse n'importe quelle application touchant au Finder sur OS X et tu verra que tu as besoin de la résolution dynamique.

    Oui et alors ? Tu peux toujours le faire...

    Utiliser Swift n'empêche pas de faire des frameworks dynamiques, et chargés au runtime. Je ne comprend pas trop ce qui te fait avoir ces oeillères et être si fermé à  dire que c'est pas possible, alors que j'ai déjà  expliqué plus haut que rien ne t'empêchait avec Swift de faire du dispatch dynamique (sans pour autant compliquer spécialement les choses).
    Que tu te bornes à  ne pas aimer Swift, c'est ton droit. Mais que tu t'obstines à  dire qu'il ne permet pas de faire des architectures en plugin et ce genre de choses alors qu'il peut, c'est un peu dommage de se limiter à  ça.

    Objective-C n'a pas été pensé pour qu'on utilise "performSelector:withObject:" partout dans notre code, personne ne va utiliser performSelector: partout là  où il peut appeler directement la méthode.
    Bah Swift c'est un peu pareil, tu vas pas t'embêter à  faire de la résolution dynamique si t'en n'as pas besoin alors que la résolution statique, bien plus efficace (et plus rapide car ne nécessitant pas d'indirection, encore + si tu actives des options comme le mode "Whole Module Optimization"), est disponible. Mais ça veut pas dire que tu ne peux pas faire de la résolution dynamique et du dynamic dispatch en Swift, loin de là , tout comme ce n'est pas parce que tout le monde écrit plutôt "[myString length]" en ObjC que tu ne peux pas écrire "[myString performSelector:@selector(length) withObject:nil]" si ça t'amuse.
  • AliGatorAliGator Membre, Modérateur
    Un peu de lecture sur le dynamic dispatch de Swift et comment on peut déplacer la barrière entre le dynamic dispatch et le static resolution selon l'accessiblité qu'on donne aux fonctions et ce que l'on expose publiquement ou qu'on garde privé dans nos modules et nos frameworks Swift : https://developer.apple.com/swift/blog/

    Et puis les méthodes comme NSBundle(...).loadNibNamed(_,owner:options:) ou même NSBundle(...).load() continuent d'exister et d'être accessibles en Swift, et les plugins peuvent tout à  fait continuer d'être écrits en Swift (du moment que tu prévois les protocoles qui vont bien permettant de te mettre d'accord sur un contrat d'interface, comme on le fait quand on fait des plugins en ObjC, tu as même un contrôle sur le typage à  la compilation)... et c'est pas prêt de changer, car comme tu le dis, c'est la base de beaucoup d'architectures OSX (mais aussi iOS et au niveau du chargement de l'UI) donc bon...
  • DrakenDraken Membre
    mai 2015 modifié #26


    C'est question d'arrêter les conneries d'environnement hyper contrôlé qui n'est pas gênant sur un gadget comme iOS quand il est question d'OS X, histoire de conserver un écosystème riche.




    OSX, un écosystème riche ? C'est un univers d'une pauvreté affligeante comparé à  la richesse et la diversité de l'écosystème Windows. Les applications sont plus jolies, plus fiables, et plus ergonomiques, mais tellement moins nombreuses. Rien que dans le domaine des jeux vidéo c'est la catastrophe absolue. Ce n'est pas pour rien que beaucoup de gens emploient Boot Camp ou des systèmes de virtualisation pour utiliser des logiciels Windows sur Mac.


     


    Je trouve amusant de te voir expliquer que l'univers OSX est riche par rapport aux applications jouets du gadget iOS, le seul écosystème logiciel réussi d'Apple, qui fait baver d'envie Microsoft et consorts.


     


    Je comprend que les applications iOS ne soient pas ta tasse de thé, toi qui est un homme du système, des technologies et des applications professionnelles lourdes. Mais cela ne ne donne pas le droit de qualifier l'écosystème iOS de noms d'oiseaux, surtout que son nombre d'utilisateurs et de son chiffre d'affaire est infiniment supérieur à  la sphère OSX.


     


    iOS est un marché de masse, OSX un secteur de niche.


  • CéroceCéroce Membre, Modérateur
    @Draken: attends, tu peux pas comparer la complexité d'un gestionnaire de liste de courses avec celle d'une suite bureautique non plus... faux pas déconner.

    Ce n'est pas parce qu'un langage permet de réaliser le premier projet qu'il convient au second, et ce dont doute yoann est justement que Swift ait les épaules assez solides pour ce genre de gros développement. C'est une question qui me parait tout à  fait légitime.
  • yoannyoann Membre


    OSX, un écosystème riche ? C'est un univers d'une pauvreté affligeante comparé à  la richesse et la diversité de l'écosystème Windows. Les applications sont plus jolies, plus fiables, et plus ergonomiques, mais tellement moins nombreuses. Rien que dans le domaine des jeux vidéo c'est la catastrophe absolue. Ce n'est pas pour rien que beaucoup de gens emploient Boot Camp ou des systèmes de virtualisation pour utiliser des logiciels Windows sur Mac.


     


    Je trouve amusant de te voir expliquer que l'univers OSX est riche par rapport aux applications jouets du gadget iOS, le seul écosystème logiciel réussi d'Apple, qui fait baver d'envie Microsoft et consorts.


     


    Je comprend que les applications iOS ne soient pas ta tasse de thé, toi qui est un homme du système, des technologies et des applications professionnelles lourdes. Mais cela ne ne donne pas le droit de qualifier l'écosystème iOS de noms d'oiseaux, surtout que son nombre d'utilisateurs et de son chiffre d'affaire est infiniment supérieur à  la sphère OSX.


     


    iOS est un marché de masse, OSX un secteur de niche.




     


    Dis de manière beaucoup plus juste, iOS est un marché de consommation là  où OS X est un marché de production. La réelle différence est là .


     


    Tu ne produit pas sur iPad, tu consomme du contenu. De fait les applications sont vachement plus light, même si elles sont potentiellement plus rentable.


     


     




    Et tu peux aussi faire de la gestion mémoire bas niveau et du dispatch dynamique en Swift.

    C'est justement exprès que j'ai pris cet exemple là  (et tu es tombé dedans les pieds joints, merci ^^)


    Oui et alors ? Tu peux toujours le faire...


    Utiliser Swift n'empêche pas de faire des frameworks dynamiques, et chargés au runtime. Je ne comprend pas trop ce qui te fait avoir ces oeillères et être si fermé à  dire que c'est pas possible, alors que j'ai déjà  expliqué plus haut que rien ne t'empêchait avec Swift de faire du dispatch dynamique (sans pour autant compliquer spécialement les choses).

    Que tu te bornes à  ne pas aimer Swift, c'est ton droit. Mais que tu t'obstines à  dire qu'il ne permet pas de faire des architectures en plugin et ce genre de choses alors qu'il peut, c'est un peu dommage de se limiter à  ça.


    Objective-C n'a pas été pensé pour qu'on utilise "performSelector:withObject:" partout dans notre code, personne ne va utiliser performSelector: partout là  où il peut appeler directement la méthode.

    Bah Swift c'est un peu pareil, tu vas pas t'embêter à  faire de la résolution dynamique si t'en n'as pas besoin alors que la résolution statique, bien plus efficace (et plus rapide car ne nécessitant pas d'indirection, encore + si tu actives des options comme le mode "Whole Module Optimization"), est disponible. Mais ça veut pas dire que tu ne peux pas faire de la résolution dynamique et du dynamic dispatch en Swift, loin de là , tout comme ce n'est pas parce que tout le monde écrit plutôt "[myString length]" en ObjC que tu ne peux pas écrire "[myString performSelector:@selector(length) withObject:nil]" si ça t'amuse.




     


    Rassure toi, on n'utilise pas des performSelector pour du dynamique mais des protocoles.


     


    Mais dans ce que tu écris tu oubli le cas non négligeable sur OS X de la modification de ce qui n'est pas exposé.


     


    Le dynamique sers à  ça. À aller ajouter ton plugin Antidote dans Mail.app qui n'expose pas ses informations par exemple.


     


     


     


    Je ne suis pas foncièrement contre Swift. C'est rigolo pour faire du dev formel. ça a du sens. Mais c'est très loin d'être un langage fait pour la production. Il y a beaucoup trop de contraintes dessus pour que ce soit tout simplement rentable.


     


     


     


    Quand je lis un cours de Swift j'ai l'impression d'entendre parler un prof de faculté qui n'a jamais fait d'entreprise de sa vie.


     


     


    Faire du formel quand on fait le programme de gestion de la ligne 14 (qui est toujours en version 1.0 depuis sa mise en exploitation) c'est carrément normal. Et dans ce genre de situation, Swift est une aide.


     


     


    Mais il faut rester terre à  terre et se dire que la plupart des projets n'ont pas les moyens d'assumer l'overhead associé. Or Swift l'imposte et Apple semble vouloir imposer Swift.

  • yoannyoann Membre

    Que ce soit sur la rentabilité, la maturité ou la solidité de Swift face aux projets complexe, j'ai de très forts doutes.


     


    Et chaque fois que je pose une question sur Swift, ça ne fait que confirmer mes doutes.


  • Joanna CarterJoanna Carter Membre, Modérateur
    mai 2015 modifié #30


    Dis de manière beaucoup plus juste, iOS est un marché de consommation là  où OS X est un marché de production. La réelle différence est là .


     


    Tu ne produit pas sur iPad, tu consomme du contenu. De fait les applications sont vachement plus light, même si elles sont potentiellement plus rentable.




     


    Quoi ? ! Je viens de travailler sur une appli iPad qui ne fait que produire les fiches de calcul et les rapports pour les pilotes d'avions privés. 


  • AliGatorAliGator Membre, Modérateur
    J'ai du mal à  voir ce que tu ne comprends pas par "c'est toujours possible de faire du dynamique avec Swift". Le runtime est toujours accessible, et l'injection aussi. C'est pas prévu à  la base pour être utilisé tous les 4 matins, tout comme performSelector ou tout comme les méthodes de <objc/runtime.h> pour faire de l'introspection, mais c'est possible quand même, tout comme en ObjC.

    Mais bon j'ai l'impression de me répéter et que malgré cela tu te cantonnes à  ta vision limitée aux bouquins permettant d'apprendre les bases de Swift, qui évidemment ne rentrent pas dans ce genre de considérations avancées pour un bouquin qui se veut faire apprendre les bases et les cas d'usage les plus courants en Swift.

    Quand j'ai appris Objective-C et commencé la programmation sous OSX, je n'ai pas commencé par apprendre et découvrir [NSBundle load], DYLD_INSERT_LIBRARIES, l'injection dynamique, le dynamic loader et les choses comme ça, et heureusement sinon j'aurai sans doute été perdu. Les bouquins qui te présentent Swift c'est pareil, ils abordent l'essentiel pour qui veut se mettre à  Swift alors qu'il n'a pas non plus un niveau d'emblée pour faire comme premiers programmes des applis full-dynamic. Ca ne veut pas dire que c'est pas possible (attends 2s, que je copie-colle cette phrase, je commence à  en avoir marre de la réécrire à  chaque fois). Tu dis toi-même qu'en tant que prof, si tu commences à  parler de ça à  tes élèves tu les perds tout de suite, donc je comprends encore moins que tu penses que les bouquins qui font apprendre Swift, même ceux qui ne sont pas pour les tout débutants, ne mentionnent pas ça directement. Pourtant si tu cherches un peu, sur la toile, sur des blogs de gens comme Samuel D.Marshall ou Mike Ash ou autre, ou que tu regardes un peu les possibilités de Swift au niveau du runtime et du chargement ou injection dynamique de bundle, tu t'apercevras que c'est possible. C'est juste pas le truc que tout le monde fait tous les jours, car tout le monde ne fait pas une application bureautique OSX super chiadée avec des plugins partout tous les jours (même en Objective-C, d'ailleurs), donc c'est loin d'être la première chose que tu apprends en Swift (comme en ObjC).
Connectez-vous ou Inscrivez-vous pour répondre.