Xcode 6 com Swift digitação super lenta e preenchimento automático


114

Sou só eu ou o Xcode 6 (6.0.1) com Swift parece muito lento quando você digita seu código, especialmente com o preenchimento automático?

Uma classe Objective-C normal, mesmo dentro de um projeto Swift, funciona quase da mesma forma que antes, então é o Swift que a mata.

Alguém mais experimentou o mesmo inconveniente? Você tem alguma ideia de como melhorar o desempenho?

  • Tentei jogar com algumas configurações, mas sem sorte.
  • É claro que também tentei reiniciar o Xcode e o computador sem sorte.
  • Nenhum outro aplicativo pesado está aberto.

Eu uso um Macbook Pro de meados de 2009 (Intel Core 2 Duo de 2,26 GHz) com 8 GB de RAM e SSD HD, o que não é nada novo, mas ainda não é um lixo completo.

É uma pena, porque eu estava animado para começar a usar o Swift e agora é realmente insuportável.

Pensamentos / dicas?

Respostas:


86
  • Saia do Xcode e reinicie o Mac não são necessários, mas preferidos.
  • Exclua o conteúdo da pasta ~ / Library / Developer / Xcode / DerivedData
  • Exclua o conteúdo ~ / Library / Caches / com.apple.dt.Xcode

Esta é uma solução temporária, mas funciona muito.

Abaixo o script usando o aplicativo Editor de scripts.

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

Como alternativa, você pode criar um alias para o seu terminal como este:

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

Você pode adicioná-lo ao seu ~/.bash_profilee digitar xcodecleanna linha de comando toda vez que quiser limpar essas duas pastas.


13

Eu também experimentei 100% + CPU enquanto digitava algum código "simples". Alguns pequenos truques para tornar o analisador rápido mais rápido pela maneira como você estrutura seu código.

Não use o concatinador "+" em strings. Para mim, isso desencadeia a lentidão muito rapidamente. Cada novo "+" traz o analisador para um rastreamento, e ele tem que reanalisar o código toda vez que você adiciona um novo caractere em algum lugar do corpo da função.

Ao invés de:

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

Use a sintaxe do modelo, que parece muito mais eficiente para analisar rapidamente:

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

Desta forma, eu basicamente noto nenhum limite em strlen com vars inline "\ (*)".

Se você tiver cálculos, que usam + / * -, divida-os em partes menores.

Ao invés de:

var result = pi * 2 * radius 

usar:

var result  = pi * 2
    result *= radius

Pode parecer menos eficiente, mas o analisador rápido é muito mais rápido dessa forma. Algumas fórmulas não compilarão, se tiverem de muitas operações, mesmo se forem matematicamente corretas.

Se você tiver alguns cálculos complexos, coloque-os em uma função. Dessa forma, o analisador pode analisá-lo uma vez e não precisa analisá-lo novamente toda vez que você alterar algo no corpo da função.

Porque se você tem um cálculo no corpo da função, de alguma forma o analisador rápido verifica se os tipos, sintaxe etc. ainda estão corretos. Se uma linha mudar acima do cálculo, algumas variáveis ​​dentro de seu cálculo / fórmula podem ter mudado. Se você colocá-lo em uma função externa, ele será validado uma vez e o swift fica feliz por estar correto e não o repassa constantemente, o que está causando o alto uso da CPU.

Dessa forma, passei de 100% a cada pressionamento de tecla para uma CPU baixa durante a digitação. Por exemplo, essas 3 linhas inseridas em linha no corpo da função podem trazer o analisador rápido para um rastreamento.

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 )

mas se eu colocá-lo em uma função e chamá-lo mais tarde, o swiftparser é muito mais 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 e XCode 6.1 ainda apresentam muitos bugs, mas se você seguir esses truques simples, a edição de código se torna aceitável novamente. Eu prefiro muito o swift, pois ele elimina os arquivos .h e usa uma sintaxe muito mais limpa. Ainda há muitos tipos de conversão necessários como "myVar as AnyObject", mas esse é o mal menor em comparação com a estrutura e sintaxe de projeto object-c complexas.

Outra experiência, experimentei o SpriteKit, que é divertido de usar, mas é bastante ineficiente se você não precisa de uma repintura constante a 60fps. Usar CALayers antigos é muito melhor para a CPU se seus "sprites" não mudarem com tanta frequência. Se você não alterar o conteúdo das camadas, a CPU ficará basicamente ociosa, mas se você tiver um aplicativo SpriteKit em execução em segundo plano, o videoplayback em outros aplicativos pode começar a falhar devido ao loop de atualização de 60fps limitado.

Às vezes, o xcode mostra erros estranhos durante a compilação, então ajuda ir ao menu "Produto> Limpar" e compilá-lo novamente, parece ser uma implementação com bugs do cache.

Outra ótima maneira de melhorar a análise quando o xcode fica preso em seu código é mencionada em outra postagem do stackoverflow aqui . Basicamente, você copia todo o conteúdo de seu arquivo .swift para um editor externo e, em seguida, função por função, copia-o de volta e vê onde está o gargalo. Isso realmente me ajudou a colocar o xcode em uma velocidade razoável novamente, depois que meu projeto enlouqueceu com 100% de CPU. enquanto copia seu código de volta, você pode refatorá-lo e tentar manter seus corpos de função curtos e funções / formulários / expressões simples (ou divididos em várias linhas).


10

Autocomplete é quebrado desde Xcode 4. Até Apple decide corrigir esse bug 2 anos de idade, a única solução, infelizmente, é transformar código de conclusão OFF nas preferências do Xcode (primeira opção da foto abaixo).

Você pode continuar aproveitando a conclusão manualmente digitando CTRL spaceou ESCquando precisar.

Esta é a única solução que funciona sempre para 100% dos casos.

insira a descrição da imagem aqui

Outra coisa que descobri recentemente é: se você usa plug-ins no Xcode, não use. Remova todos eles. Eles tornam o problema pior.


5

Você está usando o Spotify? Eu instalei o Yosemite GM com Xcode 6.1 GM em um iMac em meados de 2009 (2.66 Ghz) com o mesmo problema. Descobri que um processo chamado "SpotifyWebHelper" está sempre marcado em vermelho como não respondendo, então desativei a opção "iniciar da web" em spotify e agora Xcode parecem rodar significativamente melhor.


2

Descobri que geralmente acontece quando você:

  • têm expressões longas em uma única afirmação (veja esta resposta )
  • misture vários operadores personalizados em uma única expressão

O segundo caso parece ter sido corrigido em uma das versões mais recentes do xcode. Exemplo: defini 2 operadores personalizados <&&> e <||> e usei em uma expressão como a <&&> b <&&> c <||> d. A divisão em várias linhas resolveu o problema:

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

Espero que seu caso seja coberto por um dos 2 acima ... por favor, poste um comentário em qualquer caso


2

Tive os mesmos problemas até no Xcode 6.3

  • preenchimentos automáticos superlentos
  • indexação super lenta
  • enorme uso de CPU por swift e SourceKitService
  • enorme uso de memória por SourceKitService

Tudo isso estava acontecendo mesmo em um projeto relativamente pequeno. Tentei todas as soluções que pude encontrar:

  • excluindo ~ / Library / Developer / Xcode / DerivedData / *
  • excluindo ~ / Library / Caches / com.apple.dt.Xcode / *
  • remova todas as combinações de strings "+" do código
  • removeu todas as declarações de dicionário suspeitas

Nada disso realmente ajudou no meu projeto.

O que realmente resolveu meu problema foi:

  • colocar cada extremidade de cada classe em seu próprio arquivo
  • colocar cada extensão em seu próprio arquivo (Class + ExtName.swift)
  • colocar "métodos swift fora da classe" em seu próprio arquivo

Agora tenho quase zero uso de CPU, baixo uso de memória e conclusões decentemente rápidas.


2

Geralmente, mover a pasta de cache (DerivedData) para uma unidade SSD (especificamente no meu caso - um armazenamento externo conectado à saída do thunderbolt) melhorou drasticamente o desempenho do meu Xcode. O tempo de compilação e perguntas gerais sobre o aplicativo é cerca de 10 vezes mais rápido. Também moveu toda a pasta git para o SSD, o que melhorou drasticamente o desempenho do git.


2

Foi uma dor até o XCode 7.2.

A Apple consertou no XCode 7.3 e agora funciona perfeitamente. É super rápido e muito mais poderoso, pois parece funcionar um pouco como a busca difusa de arquivos: você não precisa digitar o início exato do método / propriedade para que ele apareça na lista de proposições.


2

Recolher todos os métodos ajuda um pouco.

command-alt-shift-left arrow fará o truque ...

Para dobrar / desdobrar métodos atuais ou se as estruturas usarem:

Dobra: command-alt-left arrow

Desdobrar: comando-alt-seta para a direita


1

SourceKitServicetambém é meio desajeitado lidar com comentários no código e os comentários incorporados também o tornam lento.

então, se você puder remover a grande quantidade de comentários incorporados como este:

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

isso também pode ajudar definitivamente.


NOTA: no meu caso, meu Xcode 7.3.1 (7D1014) foi literalmente bloqueado ao digitar qualquer letra quando o arquivo tinha cerca de 700 linhas de comentário com comentários incorporados. Inicialmente, removi aquele bloco daquele .swiftarquivo e o Xcode voltou a funcionar. Tentei adicionar meus comentários de volta parte por parte removendo comentários incorporados, ainda estava mais lento do que o normal, mas mostrava um desempenho significativamente melhor se não houvesse comentários incorporados.


1

Eu tive o mesmo problema quando a digitação estava demorando em uma classe específica e descobri que

/* Long multiline comments */

estava retardando a digitação.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.