Xcode 6 с быстрым супер медленным вводом текста и автозаполнением

Это только я или Xcode 6 (6.0.1) с Swift, кажется,медленно когда вы вводите свой код, особенно с автоподстановкой?

обычный класс Objective-C, даже если внутри проекта Swift, работает почти так же, как и раньше, поэтому Swift убивает его.

кто-нибудь еще испытывает те же неудобства? У вас есть идеи, как повысить производительность?

  • Я пытался играть с настройками, но нет удача.
  • Я также, конечно, попытался перезапустить Xcode и компьютер без успеха.
  • нет других тяжелых приложения открыты.

Я использую середину 2009 Macbook Pro (2.26 GHz Intel Core 2 Duo) с 8GB RAM и SSD HD, что не является новейшей вещью вообще, но все еще не полный мусор.

Это позор, так как я был взволнован, чтобы начать использовать Swift, и теперь это действительно невыносимо.

мысли / советы?

11 ответов


  • выход Xcode и перезагрузка Mac не требуются, но предпочтительны.
  • удалить контент папки ~ / Библиотека / Разработчик/Xcode / DerivedData
  • удалить контент ~ / Library / Caches / com.яблоко.Второзаконие.В Xcode

это временное решение, но работает значительно.

ниже сценария с помощью приложения редактора сценариев.

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

кроме того, вы можете создать псевдоним для вашего терминала вот так:

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

вы можете добавить в свой ~/.bash_profile и затем введите xcodeclean в командной строке каждый раз, когда вы хотите удалить эти две папки.


Я также испытал 100%+ CPU при вводе некоторого "простого" кода. Некоторые небольшие трюки, чтобы сделать swift-parser быстрее, как вы структурируете свой код.

не используйте конкатинатор " + " в строках. Для меня это вызывает медлительность очень быстро. Каждый новый " + " приводит синтаксический анализатор к обходу, и он должен повторно обрабатывать код каждый раз, когда вы добавляете новый символ где-то в теле функции.

вместо:

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

используйте синтаксис шаблона, который кажется гораздо эффективнее разбирать в swift:

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

таким образом, я в основном не замечаю ограничений в strlen со встроенными vars "\(*)" .

если у вас есть расчеты, которые используют + / * - затем разбить их на более мелкие части.

вместо:

var result = pi * 2 * radius 

использование:

var result  = pi * 2
    result *= radius

это может выглядеть менее эффективным, но быстрый парсер намного быстрее таким образом. Некоторые формулы не будут компилироваться, если им нужно много операций, даже если они математически правильный.

если у вас есть некоторые сложные вычисления, то поместите его в func. Таким образом, синтаксический анализатор может проанализировать его один раз и не должен переделывать его каждый раз, когда вы что-то меняете в своем теле функции.

потому что если у вас есть расчет в теле функции, то каким-то образом swift parser проверяет его каждый раз, если типы, синтаксис и т. д. по-прежнему верны. Если строка изменяется над вычислением, то некоторые vars внутри вашего вычисления / формулы могут измениться. Если вы поместите его во внешнюю функцию, тогда он будет проверен один раз, и swift счастлив, что он будет правильным и не будет постоянно переделывать его, что вызывает высокую загрузку процессора.

таким образом, я получил от 100% на каждом нажатии клавиши до низкого процессора во время ввода. Например, эти 3 строки, встроенные в тело функции, могут привести swiftparser к обходу.

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 )

но если я помещу его в func и позвоню позже, swiftparser намного быстрее

// 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 и XCode 6.1 по-прежнему очень глючит, но если вы будете следовать этим простым трюкам, редактирование кода снова станет приемлемым. Я предпочитаю swift, так как он избавляется .H файлы и использует гораздо более чистый синтаксис. По-прежнему требуется много типов , таких как "myVar as AnyObject", но это меньшее зло по сравнению со сложной структурой и синтаксисом проекта objective-C.

также еще один опыт, я попробовал SpriteKit, который интересно использовать, но его довольно эффективно, если вам не нужна постоянная перекраска на 60фпс. Использование старых CALayers намного лучше для процессора, если ваши "спрайты" не меняются так часто. Если вы не измените .содержимое слоев тогда CPU в основном простаивает, но если у вас есть приложение SpriteKit, работающее в фоновом режиме, то videoplayback в других приложениях может начать заикаться из-за жесткого цикла обновления 60fps.

иногда xcode показывает нечетные ошибки во время компиляции, то это помогает перейти в меню "продукт > очистить" и скомпилировать его снова, кажется, багги реализации из тайника.

еще один отличный способ улучшить разбор, когда xcode застревает с вашим кодом, упоминается в другом сообщении stackoverflow здесь. В основном вы копируете все содержимое из своего .swift-файл во внешний редактор, а затем функция по функции скопируйте его обратно и посмотрите, где ваше узкое место. Это на самом деле помогло мне снова получить Xcode на разумную скорость, после того, как мой проект сошел с ума со 100% CPU. при копировании кода, Вы можете переработать его и попытаться держите свои функции-тела короткими, а функции / формулы / выражения простыми (или разделенными на несколько строк).


автозаполнение нарушено с Xcode 4. Пока Apple не решит исправить эту ошибку 2 лет, единственное решение, к сожалению, - это завершить код выкл в настройках XCode (первый вариант рисунка ниже).

вы можете продолжать наслаждаться завершением вручную, набрав CTRL space или ESC когда вам это нужно.

это единственное решение, которое работает каждый раз для 100% случаев.

enter image description here

другое дело у меня недавно обнаружено: если вы используете плагины на Xcode, не делайте этого. Уберите их все. Они усугубляют проблему.


вы используете Spotify? Я установил Yosemite GM с Xcode 6.1 GM на iMac mid 2009 (2.66 Ghz), имеющий ту же проблему.Я обнаружил, что процесс под названием "SpotifyWebHelper" всегда помечен красным как не отвечающий, поэтому я отключил опцию "начать с интернета" в spotify, и теперь Xcode, похоже, работает значительно лучше.


У меня были те же проблемы даже в Xcode 6.3

  • супер медленные варианты автозаполнения
  • супер медленной индексации
  • огромное использование процессора swift и SourceKitService
  • огромное использование памяти SourceKitService

все это происходило даже в относительно небольшой проект. Я попробовал все исправления, которые смог найти:

  • удаление ~ / библиотека / разработчик / Xcode / DerivedData/*
  • удаление ~/Library/кэш/ком.яблоко.Второзаконие.Xcode/*
  • удалить все " + " строка объединения из кода
  • удалены все подозрительные объявления словарь

ни один из них не помог в моем проекте.

что на самом деле решить мою проблему:

  • размещение каждого класса в отдельном файле
  • размещение каждого расширения в своем собственном файле (Class + ExtName.swift)
  • размещение " вне класса swift методы" в своем собственном файле

теперь у меня почти нулевое использование процессора, низкое использование памяти и прилично быстрые завершения.


Как правило, перемещение папки кэша (DerivedData) на SSD - диск (в частности, в моем случае-внешнее хранилище, подключенное к выходу thunderbolt) значительно улучшило мою производительность Xcode.. Время компиляции и общее удивление вокруг приложения примерно в 10 раз быстрее.. Также переместил всю папку git на SSD, что значительно улучшило производительность git.


Это была боль до XCode 7.2.

Apple исправила его в XCode 7.3, и теперь он работает как шарм. Это супер быстрый и гораздо более мощный, как это, кажется, работает немного, как нечеткий поиск файлов : вам не обязательно вводить точное начало метод/свойство, чтобы оно появилось в списке предложений.


сворачивание всех методов немного помогает.

command-alt-shift-Стрелка влево сделает трюк...

сложить / развернуть текущие методы или если структуры используют:

Fold: command-alt-стрелка влево

развернуть: command-alt-стрелка вправо


я узнал, что обычно происходит, когда вы:

  • имеют длинные выражения в одном операторе (см. ответ)
  • смешать несколько пользовательских операторов в одном выражении

второй случай, похоже, исправлен в одном из последних выпусков xcode. Пример: я определил 2 пользовательских оператора и и использовал в выражении типа a <&&> b <&&> c <||> d. Разделение на несколько строк решило проблему:

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

Я надеюсь что ваши случаи охвачены одним из 2 выше... пожалуйста, оставьте комментарий в любом случае


SourceKitService также немного неуклюж, чтобы иметь дело с комментариями в коде и встроенные комментарии замедлить его тоже.

поэтому, если вы можете позволить себе удалить массивный blob встроенных комментариев, как это:

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

Это определенно может помочь.


Примечание: в моем случае мой Xcode 7.3.1 (7D1014) был буквально заблокирован мной, набрав любую букву, когда в файле было около 700 строк комментария со встроенным комментарии. первоначально я удалил этот блок из этого .swift файл и Xcode снова ожили. Я попытался добавить свои комментарии по частям, удалив встроенные комментарии, он был все еще медленнее, чем обычно, но он показал значительно лучшую производительность, если не было встроенных комментариев.


У меня была та же проблема, когда ввод текста отставал в определенном классе и получается, что

/* Long multiline comments */

замедление ввода.