Xcode 6 con digitazione super lenta Swift e completamento automatico


114

Sono solo io o Xcode 6 (6.0.1) con Swift sembra essere super lento quando digiti il ​​codice, specialmente con il completamento automatico?

Una normale classe Objective-C, anche se all'interno di un progetto Swift, funziona quasi come prima, quindi è Swift che la uccide.

Qualcun altro ha lo stesso inconveniente? Hai idea di come migliorare le prestazioni?

  • Ho provato a giocare con alcune impostazioni ma senza fortuna.
  • Ovviamente ho anche provato a riavviare Xcode e il computer senza fortuna.
  • Non sono aperte altre app pesanti.

Uso un Macbook Pro della metà del 2009 (Intel Core 2 Duo da 2,26 GHz) con 8 GB di RAM e SSD HD, che non è affatto l'ultima cosa, ma non è ancora una spazzatura completa.

È un peccato perché ero entusiasta di iniziare a usare Swift e ora è davvero insopportabile.

Pensieri / suggerimenti?


1
Ho gli stessi problemi che hai tu. Spesso Xcode mi dice "SourceKit terminato, editor temporaneamente limitato"
idmean

Sì, anche questo è un altro problema, non sono sicuro che siano correlati. È stato lento anche quando si verifica l'errore.
mllm

1
Sono sicuro che siano imparentati. Nella beta 5 ho visto quel messaggio ancora più spesso e l'ho visto ogni volta che il suggerimento non funzionava. (Quando ho digitato alcuni caratteri e premuto Esc per attivare il suggerimento)
idmean

1
Ho lo stesso problema. Il mio XCode utilizza oltre il 300% della CPU e rallenta la retina del mio macbook fino a una velocità lumaca. In questi giorni scrivo praticamente alla cieca e aspetto il completamento di xcode.
pkuhar

1
Ho gli stessi problemi con un MacBook Pro da 15,6 "di fine 2011 con 8 GB di RAM e un SSD. Il 90% del completamento del timecode blocca Xcode, quando controllo il monitor dell'attività vedo un utilizzo della CPU di circa il 200%. Il blocco dura da un paio di secondi a un paio di minuti
isair

Risposte:


86
  • Esci da Xcode e riavvia il Mac non sono necessari ma preferiti.
  • Elimina il contenuto della cartella ~ / Library / Developer / Xcode / DerivedData
  • Elimina il contenuto ~ / Library / Caches / com.apple.dt.Xcode

Questa è una soluzione temporale, ma funziona alla grande.

Sotto lo script utilizzando l'app 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

In alternativa, puoi creare un alias per il tuo terminale come questo:

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

Puoi aggiungerlo al tuo ~/.bash_profilee quindi digitare xcodecleansulla riga di comando ogni volta che desideri cancellare quelle due cartelle.


Bene, anche se non è vicino all'essere perfetto, sembra che la tua soluzione lo migliori in modo significativo. Segnerò come risolutivo, poiché dopo molto tempo questo è probabilmente il meglio che può ottenere. Sarei felice di sentire parlare di altri ... Grazie mille!
mllm

Il mio laptop ha impiegato quasi un minuto per rimuovere tutto il contenuto da quelle due cartelle. L'indicizzazione su Xcode ora richiede meno di 30 secondi.
Eneko Alonso

Non ha reso più veloce la digitazione e il completamento automatico, ma mi ha aiutato a liberare molto spazio dal mio Mac.
Scott Zhu

Questa risposta ha aiutato nella questione del completamento automatico, stackoverflow.com/a/29849869/1213267
Scott Zhu

13

Ho anche sperimentato 100% + CPU durante la digitazione del codice "semplice". Alcuni piccoli trucchi per rendere più veloce lo swift-parser dal modo in cui strutturi il tuo codice.

Non utilizzare il concatinatore "+" nelle stringhe. Per me questo fa scattare la lentezza molto rapidamente. Ogni nuovo "+" porta il parser a una scansione e deve analizzare il codice ogni volta che aggiungi un nuovo carattere da qualche parte nel corpo della tua funzione.

Invece di:

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

Usa la sintassi del modello che sembra molto più efficiente da analizzare in modo rapido:

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

In questo modo fondamentalmente non noto alcun limite in strlen con le variabili in linea "\ (*)".

Se disponi di calcoli che utilizzano + / * - suddividili in parti più piccole.

Invece di:

var result = pi * 2 * radius 

uso:

var result  = pi * 2
    result *= radius

Potrebbe sembrare meno efficiente, ma lo swift parser è molto più veloce in questo modo. Alcune formule non vengono compilate, se hanno molte operazioni, anche se sono matematicamente corrette.

Se hai dei calcoli complessi, inseriscili in una funzione. In questo modo il parser può analizzarlo una volta e non deve analizzarlo ogni volta che si cambia qualcosa nel corpo della funzione.

Perché se hai un calcolo nel corpo della funzione, in qualche modo il parser rapido lo controlla ogni volta se i tipi, la sintassi ecc. Sono ancora corretti. Se una riga cambia sopra il calcolo, alcune variabili all'interno del calcolo / formula potrebbero essere cambiate. Se lo metti in una funzione esterna, verrà convalidato una volta e swift è felice che sia corretto e non lo analizzi costantemente, il che causa un elevato utilizzo della CPU.

In questo modo sono passato dal 100% ad ogni pressione di un tasto a una CPU bassa durante la digitazione. Ad esempio, queste 3 linee inserite in linea nel corpo della funzione possono portare lo swiftparser a gattonare.

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 )

ma se lo metto in una funzione e lo chiamo più tardi, swiftparser è molto più veloce

// 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 e XCode 6.1 sono ancora molto buggati, ma se segui questi semplici trucchi, la modifica del codice diventa di nuovo accettabile. Preferisco molto swift, poiché elimina i file .he utilizza una sintassi molto più pulita. Ci sono ancora molti tipi di casting necessari come "myVar as AnyObject", ma questo è il male minore rispetto alla complessa struttura e sintassi del progetto Object-C.

Un'altra esperienza, ho provato lo SpriteKit, che è divertente da usare, ma è abbastanza inefficiente se non è necessario ridipingere costantemente a 60 fps. Usare i vecchi CALayer è molto meglio per la CPU se i tuoi "sprite" non cambiano spesso. Se non modifichi il contenuto dei livelli, la CPU è praticamente inattiva, ma se hai un'app SpriteKit in esecuzione in background, la riproduzione video in altre app potrebbe iniziare a balbettare a causa del ciclo di aggiornamento a 60 fps.

A volte xcode mostra strani errori durante la compilazione, quindi aiuta ad andare nel menu "Prodotto> Pulisci" e compilarlo di nuovo, sembra essere un'implementazione difettosa della cache.

Un altro ottimo modo per migliorare l'analisi quando xcode si blocca con il tuo codice è menzionato in un altro post di stackoverflow qui . Fondamentalmente copi tutti i contenuti dal tuo file .swift in un editor esterno, quindi funzione per funzione lo copia indietro e vedi dove si trova il tuo collo di bottiglia. Questo in realtà mi ha aiutato a riportare xcode a una velocità ragionevole, dopo che il mio progetto è impazzito con il 100% della CPU. durante la copia del codice, puoi rifattorizzarlo e cercare di mantenere i corpi delle funzioni brevi e le funzioni / le formule / le espressioni semplici (o divise in più righe).


Risposta molto approfondita. Forse alcuni dei suggerimenti sono ottimi come "primo soccorso", ma davvero, non ci aspettiamo che Xcode funzioni semplicemente senza passare attraverso un enorme problema?
mllm

1
sfortunatamente xcode 6.1 + swift è abbastanza instabile, quindi questi "hack" sono necessari. Apple dovrebbe correggere swift e xcode. Ma swift è molto piacevole da programmare, quindi a breve termine questo è l'unico modo per tenere a bada l'utilizzo della CPU.
Daniel Unterberger

ho apportato tutte le modifiche possibili che proponi ma sfortunatamente il mio completamento automatico fa ancora schifo Dubito che anche le clausole stenografiche potrebbero creare problemi. Intendo ritorno (a == b)? x: y
Ilker Baltaci

Bene, scrivere codice in un certo modo per rendere felice IDE è una vera assurdità
Andrey Gordeev

10

Completamento automatico è rotto dal Xcode 4. Fino a quando Apple non decida di fissare questo 2 anni bug, l'unica soluzione, purtroppo, è quello di trasformare il codice di completamento OFF sulle preferenze di XCode (prima opzione della foto sotto).

Puoi continuare a goderti il ​​completamento manualmente digitando CTRL spaceo ESCquando ne hai bisogno.

Questa è l'unica soluzione che funziona sempre per il 100% dei casi.

inserisci qui la descrizione dell'immagine

Un'altra cosa che ho scoperto di recente è: se usi plugin su Xcode, non farlo. Rimuovili tutti. Aggravano il problema.


5

Stai usando Spotify? Ho installato Yosemite GM con Xcode 6.1 GM su un iMac metà 2009 (2.66Ghz) con lo stesso problema. Ho scoperto che un processo chiamato "SpotifyWebHelper" è sempre contrassegnato in rosso come non risponde, quindi ho disabilitato l'opzione "avvia dal web" in spotify e ora Xcode sembrano funzionare significativamente meglio.


Interessante, ma per me non è correlato a Spotify ... Tuttavia mostra forse che è solo un "solito" problema di prestazioni - il che significa - cancella più risorse e funzionerà meglio. È triste perché non ho più risorse da fornire (a parte i soldi su un nuovo Mac).
mllm

2

Ho scoperto che di solito accade quando:

  • avere lunghe espressioni in una singola affermazione (vedi questa risposta )
  • combina più operatori personalizzati in una singola espressione

Il secondo caso sembra essere stato risolto in una delle ultime versioni di xcode. Esempio: ho definito 2 operatori personalizzati <&&> e <||> e li ho usati in un'espressione come a <&&> b <&&> c <||> d. La suddivisione in più righe ha risolto il problema:

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

Spero che i tuoi casi siano coperti da uno dei 2 sopra ... per favore pubblica un commento in ogni caso


5
Sfortunatamente accade anche in un progetto pulito nuovo di zecca senza niente e digitando qualcosa di semplice come "var s: Stri ...". Non appena inizio a digitare St ... sarà lento quando cerco suggerimenti per il completamento.
mllm

Sono sicuramente gli operandi per me. Avere più di un operando nella stessa riga lo causa. Grazie per la risposta. Questa dovrebbe essere la risposta giusta
Kesava

2

Ho avuto gli stessi problemi anche in Xcode 6.3

  • completamenti automatici super lenti
  • indicizzazione super lenta
  • enorme utilizzo della CPU da swift e SourceKitService
  • enorme utilizzo della memoria da parte di SourceKitService

Tutto questo stava accadendo anche in un progetto relativamente piccolo. Ho provato tutte le soluzioni che ho trovato:

  • eliminazione di ~ / Library / Developer / Xcode / DerivedData / *
  • eliminazione di ~ / Library / Caches / com.apple.dt.Xcode / *
  • rimuovere tutte le combinazioni di stringhe "+" dal codice
  • rimosse tutte le dichiarazioni sospette del dizionario

Nessuno di questi ha effettivamente aiutato nel mio progetto.

Ciò che ha effettivamente risolto il mio problema è stato:

  • ponendo ogni fine ogni classe nel proprio file
  • posizionando ogni estensione nel proprio file (Class + ExtName.swift)
  • inserendo "metodi rapidi fuori classe" nel proprio file

Ora ho un utilizzo della CPU vicino allo zero, un basso utilizzo della memoria e completamenti abbastanza veloci.


2

In generale, lo spostamento della cartella della cache (DerivedData) su un'unità SSD (in particolare nel mio caso, una memoria esterna collegata all'uscita Thunderbolt) ha notevolmente migliorato le mie prestazioni Xcode .. Il tempo di compilazione e le domande generali sull'app sono circa 10 volte più veloci .. Inoltre, è stata spostata l'intera cartella git sull'SSD, il che ha notevolmente migliorato le prestazioni di git.


In realtà nel problema originale avevo già aggiornato il mio Mac con l'unità SSD e tutto funzionava da esso incl. il sistema operativo e c'erano ancora problemi
mllm

2

È stato un dolore fino a XCode 7.2.

Apple lo ha corretto in XCode 7.3 e ora funziona come un fascino. È super veloce e molto più potente in quanto sembra funzionare un po 'come la ricerca fuzzy dei file: non è necessario digitare effettivamente l'inizio esatto del metodo / proprietà affinché appaia nell'elenco delle proposizioni.


2

Comprimere tutti i metodi aiuta un po '.

command-alt-shift-freccia sinistra farà il trucco ...

Per piegare / aprire i metodi correnti o se le strutture utilizzano:

Piega: comando-alt-freccia sinistra

Apri: comando-alt-freccia destra


1

SourceKitServiceè anche un po 'goffo gestire i commenti nel codice e anche i commenti incorporati lo rallentano.

quindi se puoi permetterti di rimuovere l'enorme massa di commenti incorporati come questo:

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

anche questo può sicuramente aiutare.


NOTA: nel mio caso il mio Xcode 7.3.1 (7D1014) mi ha letteralmente bloccato digitando qualsiasi lettera quando il file aveva circa 700 righe di commento con commenti incorporati. inizialmente ho rimosso quel blocco da quel .swiftfile e Xcode è tornato in vita. Ho provato ad aggiungere i miei commenti parte per parte rimuovendo i commenti incorporati, era ancora più lento del solito ma mostrava prestazioni significativamente migliori se non c'erano commenti incorporati.


1

Ho avuto lo stesso problema in cui la digitazione era in ritardo in una particolare classe e si scopre che

/* Long multiline comments */

stava rallentando la digitazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.