Xcode 6 con escritura superlenta Swift y autocompletado

114

¿Soy solo yo o Xcode 6 (6.0.1) con Swift parece ser muy lento cuando escribe su código, especialmente con el autocompletado?

Una clase normal de Objective-C, incluso si está dentro de un proyecto Swift, funciona casi igual que antes, por lo que es Swift quien lo mata.

¿Alguien más experimenta el mismo inconveniente? ¿Tiene alguna idea de cómo mejorar el rendimiento?

  • Intenté jugar con algunos ajustes pero no tuve suerte.
  • Por supuesto, también intenté reiniciar Xcode y la computadora sin suerte.
  • No hay otras aplicaciones pesadas abiertas.

Utilizo una Macbook Pro de mediados de 2009 (Intel Core 2 Duo de 2,26 GHz) con 8 GB de RAM y SSD HD, que no es la última novedad en absoluto, pero tampoco una completa basura.

Es una pena porque estaba emocionado de comenzar a usar Swift y ahora es realmente insoportable.

¿Pensamientos / consejos?

mllm
fuente
1
Tengo los mismos problemas que tú. A menudo, Xcode me dice "SourceKit terminado, editor temporalmente limitado"
idmean
Sí, este también es otro problema, aunque no estoy seguro de que estén relacionados. Fue lento incluso cuando ocurre ese error.
mllm
1
Estoy seguro de que están relacionados. En la beta 5 vi ese mensaje con más frecuencia, y lo vi en cualquier momento cuando la sugerencia no funcionó. (Cuando escribí algunos caracteres y presioné Esc para activar la sugerencia)
idmean
1
Tengo el mismo problema. Mi XCode usa más del 300% de la CPU y ralentiza la retina de mi macbook a una velocidad de caracol. Prácticamente escribo a ciegas estos días y espero a que se complete xcode.
pkuhar
1
Tener los mismos problemas con una MacBook Pro de 15.6 "de finales de 2011 con 8 GB de RAM y un SSD. El 90% del tiempo de finalización del código congela Xcode, cuando reviso el monitor de actividad veo ~ 200% de uso de la CPU. Las congelaciones duran un par de segundos a un par de minutos.
isair

Respuestas:

86
  • No es necesario salir de Xcode y reiniciar Mac, pero es preferible.
  • Elimina el contenido de la carpeta ~ / Library / Developer / Xcode / DerivedData
  • Elimina el contenido ~ / Library / Caches / com.apple.dt.Xcode

Esta es una solución temporal, pero funciona en gran medida.

Debajo del script usando la aplicación 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

Alternativamente, puede crear un alias para su terminal como este:

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

Puede agregar eso a su ~/.bash_profiley luego escribir xcodecleanen la línea de comando cada vez que desee borrar esas dos carpetas.

g8production - Daniele Gali8
fuente
Bueno, aunque no está cerca de ser perfecto, parece que su solución lo mejora significativamente. Voy a marcar es tan resolutivo, ya que después de bastante tiempo esto es probablemente lo mejor que se puede conseguir. Estaría feliz de saber de otros ... ¡Muchas gracias!
mllm
Mi computadora portátil tardó casi un minuto en eliminar todo el contenido de esas dos carpetas. La indexación en Xcode ahora toma menos de 30 segundos.
Eneko Alonso
No hizo que mi escritura y autocompletado fueran más rápidos, pero me ayudó a liberar bastante espacio de mi Mac.
Scott Zhu
Esta respuesta ayudó con el autocompletado, stackoverflow.com/a/29849869/1213267
Scott Zhu
13

También experimenté 100% + CPU mientras escribía un código "simple". Algunos pequeños trucos para hacer que el analizador rápido sea más rápido por la forma en que estructura su código.

No use el concatinador "+" en cadenas. Para mí, esto desencadena la lentitud muy rápidamente. Cada nuevo "+" lleva al analizador a un rastreo, y tiene que volver a analizar el código cada vez que agrega un nuevo carácter en algún lugar del cuerpo de su función.

En vez de:

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

Use la sintaxis de plantilla que parece mucho más eficiente para analizar en rápido:

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

De esta manera, básicamente noto que no hay límite en strlen con vars en línea "\ (*)".

Si tiene cálculos que usan + / *, divídalos en partes más pequeñas.

En vez de:

var result = pi * 2 * radius 

utilizar:

var result  = pi * 2
    result *= radius

Puede parecer menos eficiente, pero el analizador rápido es mucho más rápido de esta manera. Algunas fórmulas no se compilan, si tienen muchas operaciones, incluso si son matemáticamente correctas.

Si tiene algunos cálculos complejos, póngalos en una función. De esta forma, el analizador puede analizarlo una vez y no tiene que volver a analizarlo cada vez que cambia algo en el cuerpo de su función.

Porque si tiene un cálculo en el cuerpo de su función, de alguna manera el analizador rápido lo verifica cada vez que los tipos, la sintaxis, etc., siguen siendo correctos. Si una línea cambia por encima del cálculo, es posible que algunas variables dentro de su cálculo / fórmula hayan cambiado. Si lo coloca en una función externa, se validará una vez y Swift se alegra de que sea correcto y no lo analice constantemente, lo que está causando un alto uso de la CPU.

De esta manera pasé del 100% en cada pulsación de tecla a CPU baja mientras escribía. Por ejemplo, estas 3 líneas colocadas en línea en su cuerpo funcional pueden hacer que el analizador rápido se arrastre.

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 )

pero si lo pongo en una función y lo llamo más tarde, el analizador rápido es mucho más rápido

// 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 y XCode 6.1 todavía tienen muchos errores, pero si sigues estos sencillos trucos, la edición de código vuelve a ser aceptable. Prefiero mucho Swift, ya que elimina los archivos .hy usa una sintaxis mucho más limpia. Todavía se necesitan muchos tipos de conversión como "myVar como AnyObject", pero ese es el mal menor en comparación con la estructura y sintaxis del complejo proyecto objetivo-c.

También otra experiencia, probé el SpriteKit, que es divertido de usar, pero es bastante ineficaz si no necesitas un repintado constante a 60 fps. Usar CALayers antiguos es mucho mejor para la CPU si tus "sprites" no cambian tan a menudo. Si no cambia el contenido de las capas, entonces la CPU está básicamente inactiva, pero si tiene una aplicación SpriteKit ejecutándose en segundo plano, la reproducción de video en otras aplicaciones puede comenzar a tartamudear debido al ciclo de actualización de 60 fps ilimitado.

A veces, xcode muestra errores extraños durante la compilación, luego ayuda ir al menú "Producto> Limpiar" y compilarlo de nuevo, parece ser una implementación defectuosa del caché.

Otra excelente manera de mejorar el análisis cuando xcode se atasca con su código se menciona en otra publicación de stackoverflow aquí . Básicamente, copia todo el contenido de su archivo .swift en un editor externo, y luego, función por función, cópielo nuevamente y vea dónde está su cuello de botella. En realidad, esto me ayudó a que xcode volviera a alcanzar una velocidad razonable, después de que mi proyecto se volviera loco con el 100% de la CPU. mientras copia su código, puede refactorizarlo e intentar mantener sus cuerpos de función cortos y sus funciones / formuladores / expresiones simples (o divididas en varias líneas).

Daniel Unterberger
fuente
Respuesta muy completa. Quizás algunas de las sugerencias sean excelentes como "primeros auxilios", pero en realidad, ¿no esperamos que Xcode simplemente funcione sin pasar por un gran lío?
mllm
1
desafortunadamente, xcode 6.1 + swift es bastante inestable, por lo que estos "hacks" son necesarios. Apple debería arreglar swift y xcode. Pero es muy agradable programar con swift, por lo que a corto plazo esta es la única forma de mantener a raya el uso de la CPU.
Daniel Unterberger
Hice todos los cambios posibles que propones, pero desafortunadamente mi autocompletado todavía apesta. Dudo que la taquigrafía if también pueda causar problemas. ¿Alguien puede reconocer eso? Me refiero a volver (a == b)? x: y
Ilker Baltaci
Bueno, escribir código de cierta manera para hacer feliz a IDE es una verdadera tontería
Andrey Gordeev
10

Autocompletar se rompe desde Xcode 4. hasta que Apple decide solucionar este 2 años de errores, la única solución, por desgracia, es convertir el código de terminación OFF de las preferencias del XCode (primera opción de la foto de abajo).

Puede seguir disfrutando de la finalización manualmente escribiendo CTRL spaceo ESCcuando lo necesite.

Esta es la única solución que funciona siempre para el 100% de los casos.

ingrese la descripción de la imagen aquí

Otra cosa que he descubierto recientemente es: si usa complementos en Xcode, no lo haga. Quítelos todos. Empeoran el problema.

Pato
fuente
5

¿Estás usando Spotify? Instalé Yosemite GM con Xcode 6.1 GM en un iMac a mediados de 2009 (2.66Ghz) que tenía el mismo problema. Descubrí que un proceso llamado "SpotifyWebHelper" siempre está marcado en rojo como no responde, así que deshabilité la opción "comenzar desde la web" en Spotify y ahora Xcode parecen funcionar significativamente mejor.

Eugenio Baglieri
fuente
Interesante, pero para mí no está relacionado con Spotify ... Sin embargo, muestra tal vez que es solo un problema de rendimiento "habitual", es decir, borre más recursos y funcionará mejor. Eso es triste porque no tengo más recursos para proporcionar (aparte del dinero en una nueva Mac).
mllm
2

Descubrí que eso suele pasar cuando tú:

  • tener expresiones largas en una sola declaración (ver esta respuesta )
  • mezclar varios operadores personalizados en una sola expresión

El segundo caso parece estar solucionado en una de las últimas versiones de xcode. Ejemplo: definí 2 operadores personalizados <&&> y <||>, y los usé en una expresión como a <&&> b <&&> c <||> d. La división en varias líneas resolvió el problema:

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

Espero que sus casos estén cubiertos por uno de los 2 anteriores ... publique un comentario en cualquier caso

Antonio
fuente
5
Desafortunadamente, también ocurre en un nuevo proyecto limpio sin nada y con algo tan simple como "var s: Stri ...". Tan pronto como empiece a escribir St ... se ralentizará al buscar sugerencias de finalización.
mllm
Definitivamente son los operandos para mí. Tener más de un operando en la misma línea lo causa. Gracias por la respuesta. Esta debería ser la respuesta correcta
Kesava
2

Tuve los mismos problemas incluso en Xcode 6.3

  • autocompletados súper lentos
  • indexación súper lenta
  • enorme uso de CPU por swift y SourceKitService
  • enorme uso de memoria por SourceKitService

Todo esto sucedía incluso en proyectos relativamente pequeños. Probé todas las soluciones que pude encontrar:

  • eliminando ~ / Library / Developer / Xcode / DerivedData / *
  • eliminando ~ / Library / Caches / com.apple.dt.Xcode / *
  • eliminar todas las combinaciones de cadenas "+" del código
  • eliminó todas las declaraciones sospechosas del diccionario

Ninguno de estos ayudó realmente en mi proyecto.

Lo que realmente resolvió mi problema fue:

  • colocando cada extremo de cada clase en su propio archivo
  • colocando todas y cada una de las extensiones en su propio archivo (Class + ExtName.swift)
  • colocar "métodos rápidos fuera de clase" en su propio archivo

Ahora tengo casi cero uso de CPU, bajo uso de memoria y finalizaciones decentemente rápidas.

Matej Ukmar
fuente
2

En general, mover la carpeta de caché (DerivedData) a una unidad SSD (específicamente en mi caso, un almacenamiento externo conectado a la salida Thunderbolt) ha mejorado drásticamente el rendimiento de mi Xcode. El tiempo de compilación y las preguntas generales sobre la aplicación son aproximadamente 10 veces más rápidas .. También movió toda la carpeta git al SSD, lo que mejoró drásticamente el rendimiento de git.

brkeyal
fuente
En realidad, en el problema original, ya había actualizado mi mac con una unidad SSD y todo funcionó, incluido. el sistema operativo, y todavía había problemas
mllm
2

Fue una molestia hasta XCode 7.2.

Apple lo arregló en XCode 7.3 y ahora funciona de maravilla. Es súper rápido y mucho más poderoso, ya que parece funcionar un poco como la búsqueda difusa de archivos: no es necesario escribir el comienzo exacto del método / propiedad para que aparezca en la lista de proposiciones.

Bioche
fuente
2

Colapsar todos los métodos ayuda un poco.

command-alt-shift-left arrow hará el truco ...

Para doblar / desplegar los métodos actuales o si las estructuras usan:

Plegar: comando-alt-flecha izquierda

Despliegue: comando-alt-flecha derecha

ruidoso
fuente
1

SourceKitServiceTambién es un poco torpe lidiar con los comentarios en el código y los comentarios incrustados también lo ralentizan.

así que si puede permitirse eliminar la masa masiva de comentarios incrustados como este:

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

eso definitivamente también puede ayudar.


NOTA: en mi caso, mi Xcode 7.3.1 (7D1014) me bloqueó literalmente al escribir cualquier letra cuando el archivo tenía alrededor de 700 líneas de comentario con comentarios incrustados. inicialmente eliminé ese bloque de ese .swiftarchivo y Xcode ha vuelto a la vida. Intenté agregar mis comentarios parte por parte eliminando los comentarios incrustados, todavía era más lento de lo habitual, pero mostraba un rendimiento significativamente mejor si no había comentarios incrustados.

holex
fuente
1

Tuve el mismo problema en el que la escritura se retrasó en una clase en particular y resulta que

/* Long multiline comments */

estaba ralentizando la escritura.

Aziz Akgul
fuente