Xcode 6 avec saisie rapide et autocomplétion Swift

114

Est-ce juste moi ou Xcode 6 (6.0.1) avec Swift semble être super lent lorsque vous tapez votre code, en particulier avec la saisie semi-automatique?

Une classe Objective-C normale, même si elle se trouve dans un projet Swift, fonctionne presque de la même manière qu'avant, c'est donc Swift qui la tue.

Quelqu'un d'autre éprouve-t-il le même inconvénient? Avez-vous une idée de la façon d'améliorer les performances?

  • J'ai essayé de jouer avec certains réglages mais pas de chance.
  • J'ai aussi bien sûr essayé de redémarrer Xcode et l'ordinateur sans succès.
  • Aucune autre application lourde n'est ouverte.

J'utilise un Macbook Pro mi-2009 (2,26 GHz Intel Core 2 Duo) avec 8 Go de RAM et SSD HD, ce qui n'est pas du tout la nouveauté, mais ce n'est toujours pas une poubelle complète.

C'est dommage car j'étais impatient de commencer à utiliser Swift et c'est maintenant vraiment insupportable.

Réflexions / conseils?

mllm
la source
1
J'ai les mêmes problèmes que vous. Souvent Xcode me dit "SourceKit terminé, éditeur temporairement limité"
idmean
Ouais, c'est aussi un autre problème, je ne suis pas sûr qu'ils soient liés. C'était lent même lorsque cette erreur se produit.
mllm
1
Je suis sûr qu'ils sont liés. Dans la version bêta 5, j'ai vu ce message encore plus souvent, et je l'ai vu à tout moment lorsque la suggestion ne fonctionnait pas. (Quand j'ai tapé quelques caractères et appuyé sur Echap pour déclencher la suggestion)
idmean
1
J'ai le même problème. Mon XCode utilise 300% + du processeur et ralentit la rétine de mon macbook à une vitesse d'escargot. Je tape à peu près aveuglément ces jours-ci et j'attends que xcode se termine.
pkuhar
1
J'ai les mêmes problèmes avec un MacBook Pro 15,6 "fin 2011 avec 8 Go de RAM et un SSD. 90% de l'achèvement du code temporel gèle Xcode, lorsque je vérifie le moniteur d'activité, je vois une utilisation du processeur d'environ 200%. Se fige au bout de quelques secondes à quelques minutes.
isair

Réponses:

86
  • Quitter Xcode et redémarrer le Mac ne sont pas obligatoires mais préférés.
  • Supprimer le contenu du dossier ~ / Library / Developer / Xcode / DerivedData
  • Supprimer le contenu ~ / Library / Caches / com.apple.dt.Xcode

C'est une solution temporelle, mais qui fonctionne énormément.

Sous le script à l'aide de l'application Script Editor.

tell application "Terminal"
    do script "rm -frd ~/Library/Developer/Xcode/DerivedData/*"
    do script "rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"
end tell

Alternativement, vous pouvez créer un alias pour votre terminal comme ceci:

alias xcodeclean="rm -frd ~/Library/Developer/Xcode/DerivedData/* && rm -frd ~/Library/Caches/com.apple.dt.Xcode/*"

Vous pouvez l'ajouter à votre ~/.bash_profile, puis taper xcodecleansur la ligne de commande chaque fois que vous souhaitez effacer ces deux dossiers.

g8production - Daniele Gali8
la source
Eh bien, même si elle n'est pas proche d'être parfaite, il semble que votre solution l'améliore considérablement. Je vais marquer comme résolvant, car après un certain temps, c'est probablement le meilleur qu'il puisse obtenir. Serait heureux d'entendre parler des autres ... Merci beaucoup!
mllm
Il a fallu près d'une minute à mon ordinateur portable pour supprimer tout le contenu de ces deux dossiers. L'indexation sur Xcode prend désormais moins de 30 secondes.
Eneko Alonso
Cela n'a pas accéléré ma saisie et ma saisie semi-automatique, mais cela m'a aidé à libérer beaucoup d'espace sur mon Mac.
Scott Zhu
Cette réponse a aidé sur la chose de l' auto
Scott Zhu
13

J'ai également expérimenté 100% + CPU en tapant du code "simple". Quelques petites astuces pour accélérer l'analyseur rapide par la façon dont vous structurez votre code.

N'utilisez pas le concatinateur "+" dans les chaînes. Pour moi, cela déclenche la lenteur très rapidement. Chaque nouveau "+" amène l'analyseur à une analyse, et il doit analyser le code chaque fois que vous ajoutez un nouveau caractère quelque part dans le corps de votre fonction.

Au lieu de:

var str = "This" + String(myArray.count) + " is " + String(someVar)

Utilisez la syntaxe template qui semble beaucoup plus efficace à analyser en swift:

var str = "This \(myArray.count) is \(someVar)"

De cette façon, je ne remarque essentiellement aucune limite dans strlen avec les variables en ligne "\ (*)".

Si vous avez des calculs utilisant + / * -, divisez-les en parties plus petites.

Au lieu de:

var result = pi * 2 * radius 

utilisation:

var result  = pi * 2
    result *= radius

Cela peut sembler moins efficace, mais l'analyseur rapide est beaucoup plus rapide de cette façon. Certaines formules ne se compilent pas, si elles ont trop d'opérations, même si elles sont mathématiquement correctes.

Si vous avez des calculs complexes, mettez-les dans un func. De cette façon, l'analyseur peut l'analyser une fois et n'a pas besoin de le réanalyser chaque fois que vous modifiez quelque chose dans votre corps de fonction.

Parce que si vous avez un calcul dans le corps de votre fonction, l'analyseur rapide le vérifie à chaque fois si les types, la syntaxe, etc. sont toujours corrects. Si une ligne change au-dessus du calcul, il se peut que certaines variables de votre calcul / formule aient changé. Si vous le placez dans une fonction externe, il sera validé une fois et Swift est heureux qu'il soit correct et ne le répète pas constamment, ce qui entraîne une utilisation élevée du processeur.

De cette façon, je suis passé de 100% à chaque pression de touche à un processeur faible en tapant. Par exemple, ces 3 lignes mises en ligne dans votre corps de fonction peuvent amener le swiftparser à une analyse.

let fullPath =  "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"
let spacesData  = NSDictionary(contentsOfFile: fullPath )! // as Dictionary<String, AnyObject>
let spaces : AnyObject   = spacesData["SpacesDisplayConfiguration"]!["Management Data"]!!["Monitors"]!![0]["Spaces"]!! 

println ( spaces )

mais si je le mets dans un func et que je l'appelle plus tard, swiftparser est beaucoup plus rapide

// some crazy typecasting here to silence the parser
// Autodetect of Type from Plist is very rudimentary, 
// so you have to teach swift your types
// i hope this will get improved in swift in future
// would be much easier if one had a xpath filter with
// spacesData.getxpath( "SpacesDisplayConfiguration/Management Data/Monitors/0/Spaces" ) as Array<*> 
// and xcode could detect type from the plist automatically
// maybe somebody can show me a more efficient way to do it
// again to make it nice for the swift parser, many vars and small statements
func getSpacesDataFromPlist() -> Array<Dictionary<String, AnyObject>> {
  let fullPath =  "\(NSHomeDirectory())/Library/Preferences/com.apple.spaces.plist"

  let spacesData  = NSDictionary(contentsOfFile: fullPath )!    as Dictionary<String, AnyObject>
  let sdconfig    = spacesData["SpacesDisplayConfiguration"]    as Dictionary<String, AnyObject>
  let mandata     = sdconfig["Management Data"]                 as Dictionary<String, AnyObject> 
  let monitors    = mandata["Monitors"]                         as Array<Dictionary<String, AnyObject>> 
  let monitor     = monitors[0]                                 as Dictionary<String, AnyObject>
  let spaces      = monitor["Spaces"]                           as Array<Dictionary<String, AnyObject>>

  return spaces
}

func awakeFromNib() {
  ....
  ... typing here ...

  let spaces = self.getSpacesDataFromPlist()
  println( spaces) 
}

Swift et XCode 6.1 sont toujours très bogués, mais si vous suivez ces astuces simples, l'édition de code redevient acceptable. Je préfère beaucoup swift, car il supprime les fichiers .h et utilise une syntaxe beaucoup plus propre. Il y a encore beaucoup de castes de types nécessaires comme "myVar as AnyObject", mais c'est le plus petit mal comparé à la structure et à la syntaxe complexes du projet objective-c.

Autre expérience également, j'ai essayé le SpriteKit, qui est amusant à utiliser, mais il est assez inefficace si vous n'avez pas besoin de repeindre constamment à 60 ips. L'utilisation d'anciens CALayers est bien meilleure pour le CPU si vos "sprites" ne changent pas souvent. Si vous ne modifiez pas le contenu des couches, le processeur est essentiellement inactif, mais si vous avez une application SpriteKit en arrière-plan, la lecture vidéo dans d'autres applications peut commencer à bégayer en raison de la boucle de mise à jour à 60 ips.

Parfois, xcode montre des erreurs étranges lors de la compilation, puis il aide à aller dans le menu "Produit> Nettoyer" et à le recompiler, semble être une implémentation boguée du cache.

Un autre excellent moyen d'améliorer l'analyse lorsque xcode est bloqué avec votre code est mentionné dans un autre article de stackoverflow ici . Fondamentalement, vous copiez tout le contenu de votre fichier .swift dans un éditeur externe, puis fonction par fonction, copiez-le et voyez où se trouve votre goulot d'étranglement. Cela m'a en fait aidé à ramener xcode à une vitesse raisonnable, après que mon projet soit devenu fou avec 100% de CPU. tout en recopiant votre code, vous pouvez le refactoriser et essayer de garder vos corps de fonctions courts et les fonctions / formulaires / expressions simples (ou divisés en plusieurs lignes).

Daniel Unterberger
la source
Réponse très complète. Peut-être que certaines des suggestions sont excellentes en tant que «premiers secours», mais vraiment, ne nous attendons-nous pas à ce que Xcode fonctionne simplement sans passer par un tracas énorme?
mllm
1
malheureusement xcode 6.1 + swift est assez instable, donc ces «hacks» sont nécessaires. Apple devrait corriger swift et xcode. Mais swift est très agréable à programmer, donc à court terme, c'est le seul moyen de garder l'utilisation du processeur à distance.
Daniel Unterberger
J'ai fait tous les changements possibles que vous proposez, mais malheureusement, mon autocomplétion est toujours nul.Je doute que la sténographie si les clauses pouvaient aussi causer des problèmes. Je veux dire retour (a == b)? x: y
Ilker Baltaci
Eh bien, écrire du code d'une certaine manière pour rendre l'IDE heureux est un vrai non
Andrey Gordeev
10

Autocomplete est cassé depuis Xcode 4. Jusqu'à ce qu'Apple décide de corriger ce bug de 2 ans, la seule solution, malheureusement, est de transformer la complétion de code OFF sur les préférences de XCode (première option de l'image ci - dessous).

Vous pouvez continuer à profiter de l'achèvement manuel en tapant CTRL spaceouESC lorsque vous en avez besoin.

C'est la seule solution qui fonctionne à chaque fois pour 100% des cas.

entrez la description de l'image ici

Une autre chose que j'ai découverte récemment est: si vous utilisez des plugins sur Xcode, ne le faites pas. Retirez-les tous. Ils aggravent le problème.

canard
la source
5

Utilisez-vous Spotify? J'ai installé Yosemite GM avec Xcode 6.1 GM sur un iMac mi-2009 (2.66Ghz) ayant le même problème.J'ai constaté qu'un processus appelé "SpotifyWebHelper" est toujours marqué en rouge comme ne répondant pas, j'ai donc désactivé l'option "démarrer à partir du Web" dans spotify et maintenant Xcode semblent fonctionner beaucoup mieux.

Eugenio Baglieri
la source
Intéressant, mais pour moi ce n'est pas lié à Spotify ... Cela montre cependant peut-être que c'est juste un problème de performance "habituel" - c'est-à-dire - dégagez plus de ressources et cela fonctionnera mieux. C'est triste car je n'ai plus de ressources à fournir (à part de l'argent sur un nouveau mac).
mllm
2

J'ai découvert que cela se produit généralement lorsque vous:

  • avoir de longues expressions dans une seule déclaration (voir cette réponse )
  • mélanger plusieurs opérateurs personnalisés dans une seule expression

Le deuxième cas semble être résolu dans l'une des dernières versions de xcode. Exemple: j'ai défini 2 opérateurs personnalisés <&&> et <||>, et utilisé dans une expression comme a <&&> b <&&> c <||> d. La division en plusieurs lignes a résolu le problème:

let r1 = a <&&> b
let r2 = r1 <&&> c
let r3 = r2 <||> d

J'espère que votre cas est couvert par l'un des 2 ci-dessus ... veuillez poster un commentaire dans les deux cas

Antonio
la source
5
Malheureusement, cela arrive aussi dans un tout nouveau projet propre sans rien dedans et en tapant quelque chose d'aussi simple que "var s: Stri ...". Dès que je commence à taper St ... il ralentira lors de la recherche des suggestions de complétion.
mllm
C'est définitivement les opérandes pour moi. Le fait d'avoir plus d'un opérande dans la même ligne le provoque. Merci d'avoir répondu. Cela devrait être la bonne réponse
Kesava
2

J'ai eu les mêmes problèmes même dans Xcode 6.3

  • Saisie semi-automatique très lente
  • indexation très lente
  • énorme utilisation du processeur par swift et SourceKitService
  • énorme utilisation de la mémoire par SourceKitService

Tout cela se produisait même dans un projet relativement petit. J'ai essayé tous les correctifs que j'ai pu trouver:

  • suppression de ~ / Library / Developer / Xcode / DerivedData / *
  • suppression de ~ / Library / Caches / com.apple.dt.Xcode / *
  • supprimer toutes les combinaisons de chaînes "+" du code
  • supprimé toutes les déclarations de dictionnaire suspectes

Aucun de ceux-ci n'a vraiment aidé dans mon projet.

Ce qui a réellement résolu mon problème était:

  • placer chaque extrémité chaque classe dans son propre fichier
  • placer chaque extension dans son propre fichier (Class + ExtName.swift)
  • placer des "méthodes swift hors classe" dans son propre fichier

Maintenant, j'ai une utilisation presque nulle du processeur, une faible utilisation de la mémoire et des achèvements décemment rapides.

Matej Ukmar
la source
2

En général, déplacer le dossier de cache (DerivedData) vers un lecteur SSD (en particulier dans mon cas - un stockage externe connecté à la sortie Thunderbolt) a considérablement amélioré mes performances Xcode. Le temps de compilation et les interrogations générales sur l'application sont environ 10 fois plus rapides. Également déplacé l'ensemble du dossier git vers le SSD, ce qui a considérablement amélioré les performances de git.

brkeyal
la source
En fait, dans le problème d'origine, j'avais déjà mis à niveau mon mac avec un lecteur SSD et tout fonctionnait à partir de celui-ci, y compris. le système d'exploitation, et il y avait toujours des problèmes
mllm
2

C'était pénible jusqu'à XCode 7.2.

Apple l'a corrigé dans XCode 7.3 et maintenant cela fonctionne comme un charme. C'est super rapide et beaucoup plus puissant car cela semble fonctionner un peu comme la recherche floue de fichiers: vous n'avez pas à taper le début exact de la méthode / propriété pour qu'elle apparaisse dans la liste des propositions.

Bioche
la source
2

Réduire toutes les méthodes aide un peu.

commande-alt-shift-left arrow fera l'affaire ...

Pour plier / déplier les méthodes actuelles ou si les structures utilisent:

Plier: commande-alt-flèche gauche

Déplier: commande-alt-flèche droite

Rowdyruckus
la source
1

SourceKitServiceest également un peu maladroit de traiter les commentaires dans le code et les commentaires intégrés le ralentissent également.

donc si vous pouvez vous permettre de supprimer le blob massif de commentaires intégrés comme celui-ci:

/*
 * comment 
    /*
     * embedded comment
     */
 */

cela peut certainement aider aussi.


REMARQUE: dans mon cas, mon Xcode 7.3.1 (7D1014) m'a littéralement empêché de taper une lettre lorsque le fichier contenait environ 700 lignes de commentaires avec des commentaires intégrés. Au départ, j'ai supprimé ce bloc de ce .swiftfichier et Xcode est redevenu vivant. J'ai essayé d'ajouter mes commentaires partie par partie en supprimant les commentaires intégrés, c'était toujours plus lent que d'habitude mais cela montrait des performances nettement meilleures s'il n'y avait pas de commentaires intégrés.

holex
la source
1

J'ai eu le même problème lorsque la frappe était à la traîne dans une classe particulière et il s'avère que

/* Long multiline comments */

ralentissait la frappe.

Aziz Akgul
la source