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

115

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

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

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

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

Я использую Macbook Pro середины 2009 года (Intel Core 2 Duo 2,26 ГГц) с 8 ГБ ОЗУ и твердотельным накопителем HD, что совсем не новинка, но все же не полный мусор.

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

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

mllm
источник
1
У меня такие же проблемы, как и у вас. Часто Xcode сообщает мне «SourceKit прекращен, редактор временно ограничен»
idmean
Да, это еще одна проблема, хотя я не уверен, что они связаны. Это было медленно, даже когда возникала эта ошибка.
mllm
1
Я уверен, что они связаны. В бета-версии 5 я видел это сообщение еще чаще, и я видел это всякий раз, когда предложение не сработало. (Когда я набрал несколько символов и нажал Esc, чтобы вызвать предложение)
idmean
1
У меня та же проблема. Мой XCode использует 300% + ЦП и замедляет сетчатку моего MacBook до скорости улитки. В наши дни я в основном печатаю вслепую и жду завершения xcode.
pkuhar
1
Имеются те же проблемы с 15,6-дюймовым MacBook Pro конца 2011 года с 8 ГБ ОЗУ и твердотельным накопителем. 90% завершения временного кода приводит к зависанию Xcode, когда я проверяю монитор активности, я вижу ~ 200% загрузки ЦП. до пары минут.
isair

Ответы:

86
  • Выйти из Xcode и перезапустить Mac не требуется, но желательно.
  • Удалите содержимое папки ~ / Library / Developer / Xcode / DerivedData
  • Удалите содержимое ~ / Library / Caches / com.apple.dt.Xcode

Это временное решение, но оно отлично работает.

Ниже скрипт с использованием приложения 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

В качестве альтернативы вы можете создать псевдоним для своего терминала следующим образом:

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

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

g8production - Даниэле Гали8
источник
Что ж, хотя он и не близок к совершенству, похоже, что ваше решение его значительно улучшает. Я отмечу, что это решение как решение, так как спустя довольно долгое время это, вероятно, лучшее, что он может получить. Был бы рад услышать о других ... Большое спасибо!
mllm
Моему ноутбуку потребовалось почти минуту, чтобы удалить все содержимое этих двух папок. Индексирование в Xcode теперь занимает менее 30 секунд.
Энеко Алонсо
Это не ускорило мой набор текста и автозаполнение, но помогло мне освободить довольно много места на моем Mac.
Скотт Чжу
Этот ответ помог с автозаполнением, stackoverflow.com/a/29849869/1213267
Скотт Чжу
13

Я также испытал 100% + CPU при наборе "простого" кода. Несколько маленьких уловок, которые помогут ускорить анализатор за счет структурирования кода.

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

Вместо того:

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

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

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

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

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

Вместо того:

var result = pi * 2 * radius 

использовать:

var result  = pi * 2
    result *= radius

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

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

Потому что, если у вас есть вычисление в теле вашей функции, то каким-то образом быстрый синтаксический анализатор проверяет его каждый раз, если типы, синтаксис и т. Д. Все еще верны. Если строка над расчетом изменится, то некоторые переменные внутри вашего расчета / формулы могли измениться. Если вы поместите его во внешнюю функцию, тогда он будет проверен один раз, и 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 )

но если я вставлю его в функцию и позвоню позже, 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 намного лучше для ЦП, если ваши «спрайты» не меняются так часто. Если вы не измените содержимое слоев, то ЦП в основном простаивает, но если у вас есть приложение SpriteKit, работающее в фоновом режиме, воспроизведение видео в других приложениях может начать прерываться из-за жестко ограниченного цикла обновления 60 кадров в секунду.

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

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

Даниэль Унтербергер
источник
Очень обстоятельный ответ. Может быть, некоторые из предложений хороши в качестве «первой помощи», но на самом деле, разве мы не ожидаем, что Xcode будет просто работать без огромных хлопот?
mllm 02
1
К сожалению, xcode 6.1 + swift довольно нестабилен, поэтому эти «хаки» необходимы. Apple должна исправить swift и xcode. Но с Swift очень приятно программировать, так что в краткосрочной перспективе это единственный способ сдержать загрузку ЦП.
Daniel Unterberger
Я внес все возможные изменения, которые вы предлагаете, но, к сожалению, мое автозаполнение все еще отстой. Я сомневаюсь, что это сокращенное условие if тоже может вызвать проблемы. Может ли кто-нибудь это признать? Я про возврат (а == б)? x: y
Ilker Baltaci
Что ж, писать код определенным образом, чтобы сделать IDE счастливой, - настоящая ерунда,
Андрей Гордеев
10

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

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

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

введите описание изображения здесь

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

Утка
источник
5

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

Эухенио Бальери
источник
Интересно, но для меня это не связано со Spotify ... Тем не менее, это показывает, что, возможно, это просто «обычная» проблема с производительностью, то есть очистите больше ресурсов, и она будет работать лучше. Это печально, так как у меня больше нет ресурсов (кроме денег на новый Mac).
mllm 08
2

Я выяснил, что обычно бывает, когда вы:

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

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

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

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

Антонио
источник
5
К сожалению, это также происходит в совершенно новом чистом проекте, в котором ничего нет, и при вводе чего-то столь же простого, как "var s: Stri ...". Как только я начну набирать St ..., поиск предложений по завершению будет вялым.
mllm
Это определенно операнды для меня. Причиной этого является наличие более одного операнда в одной строке. Спасибо за ответ. Это должен быть правильный ответ
Кесава
2

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

  • супер медленное автозаполнение
  • сверхмедленное индексирование
  • огромная загрузка ЦП Swift и SourceKitService
  • огромное использование памяти SourceKitService

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

  • удаление ~ / Library / Developer / Xcode / DerivedData / *
  • удаление ~ / Library / Caches / com.apple.dt.Xcode / *
  • удалить все комбинации "+" String из кода
  • удалены все подозрительные объявления словаря

Ничего из этого не помогло моему проекту.

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

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

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

Матей Укмар
источник
2

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

brkeyal
источник
На самом деле в исходной проблеме я уже обновил свой Mac с SSD-накопителем, и все работало с него, включая. ОС, и все равно были проблемы
mllm 03
2

До XCode 7.2 это было мучительно.

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

биохимические
источник
2

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

command-alt-shift-left arrow сделает свое дело ...

Чтобы свернуть / развернуть текущие методы или если в структурах используется:

Сгиб: command-alt-стрелка влево

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

rowdyruckus
источник
1

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

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

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

это тоже может помочь.


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

holex
источник
1

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

/* Long multiline comments */

замедлял набор текста.

Азиз Акгуль
источник