Xcode 6具有Swift超慢键入和自动补全功能


114

是我还是在键入代码时使用Swift的Xcode 6(6.0.1)似乎超级慢,尤其是在自动完成时?

即使在Swift项目中,普通的Objective-C类的工作原理也几乎与以前相同,因此Swift会杀死它。

其他人也会遇到同样的不便吗?您对如何提高性能有任何想法吗?

  • 我尝试了一些设置,但没有运气。
  • 当然,我也尝试过重启Xcode和没有运气的计算机。
  • 没有其他重型应用程序打开。

我使用具有8GB RAM和SSD HD的2009年中Macbook Pro(2.26 GHz Intel Core 2 Duo),这虽然不是最新的东西,但仍然不是一个完整的垃圾。

感到遗憾的是,我开始使用Swift感到非常兴奋,现在实在无法忍受。

有想法/提示吗?


1
我和你有同样的问题。Xcode经常告诉我“ SourceKit已终止,编辑器暂时受到限制”
idmean 2014年

是的,这也是另一个问题,不过我不确定它们是否相关。即使发生此错误,速度也很慢。
mllm 2014年

1
我确定他们有关系。在beta 5中,我经常看到该消息,并且在建议不起作用的任何时间都可以看到。(当我键入一些字符并按Esc触发建议时)
idmean 2014年

1
我也有同样的问题。我的XCode使用300%+的CPU,并将Macbook视网膜的速度降低到蜗牛速度。这几天我几乎盲目地打字,等待xcode完成。
pkuhar 2014年

1
2011年末的15.6英寸MacBook Pro配备8 GB RAM和SSD时也遇到了同样的问题。当我检查活动监视器时,看到90%的时间代码完成会冻结Xcode,我发现〜200%的CPU使用率。冻结持续了几秒钟到几分钟
-isair

Answers:


86
  • 不需要Xcode并重新启动Mac,但首选。
  • 删除内容的文件夹〜/资源库/开发/的Xcode / DerivedData的
  • 删除内容〜/ Library / Caches / com.apple.dt.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每次想清除这两个文件夹时在命令行上键入。


好吧,尽管它尚不完美,但看起来您的解决方案确实可以改善它。我要标记的是解决问题,因为很长一段时间后,这可能是最好的解决方法。很高兴听到别人的消息……非常感谢!
mllm 2014年

我的笔记本电脑花了几乎一分钟时间才从这两个文件夹中删除了所有内容。现在,在Xcode上建立索引只需不到30秒。
Eneko Alonso

它并没有使我的键入和自动完成速度更快,但是它确实帮助我从Mac中释放了很多空间。
朱朱

这个答案对自动补全有帮助,stackoverflow.com
Scott Zhu

13

在键入一些“简单”代码时,我还体验了100%+的CPU。通过构造代码的方式可以使快速解析器更快的一些小技巧。

请勿在字符串中使用“ +”修饰符。对我来说,这会很快触发缓慢。每个新的“ +”都会使解析器爬行,并且每次在函数体中的某个位置添加新的char时,它都必须重新解析代码。

代替:

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

使用模板语法来快速解析似乎效率更高:

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

这样,我基本上注意到inline vars“ \(*)”在strlen中没有限制。

如果您有使用+ / *-的计算,则将其拆分为较小的部分。

代替:

var result = pi * 2 * radius 

用:

var result  = pi * 2
    result *= radius

它看起来效率较低,但是快速解析器以这种方式更快。即使某些公式必须进行许多运算,即使它们在数学上是正确的,它们也不会编译。

如果您有一些复杂的计算,则将其放在一个函数中。这样,解析器可以解析一次,而不必每次在函数体中进行更改时都重新解析它。

因为如果您在函数体内有一个计算,那么无论类型,语法等是否仍然正确,快速解析器都会以某种方式对其进行检查。如果一行在计算上方变化,则您的计算/公式中的某些变量可能已更改。如果将其放在外部函数中,则将对其进行一次验证,而swift很高兴它将是正确的,并且不会不断对其进行重新解析,这会导致CPU使用率很高。

这样我在打字时从每次按键的100%降低到CPU不足。例如,内联在函数主体中的这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,该工具使用起来很有趣,但如果您不需要以60fps的速度进行恒定重绘,则效率很低。如果您的“精灵”不经常更改,则使用旧的CALayers对于CPU会更好。如果不更改图层的.content,则CPU基本上处于空闲状态,但是如果您在后台运行SpriteKit应用,则由于受限的60fps更新循环,其他应用中的视频播放可能会开始停顿。

有时xcode会在编译时显示奇数错误,然后进入菜单“ Product> Clean”并再次编译将很有帮助,这似乎是缓存的错误实现。

当xcode被代码卡住时,另一种改善解析的好方法在此处的另一个stackoverflow文章中提到。基本上,您将所有内容从.swift文件复制到外部编辑器中,然后通过函数将其复制回去,以查看瓶颈所在。在我的项目疯狂使用100%CPU之后,这实际上帮助我将xcode再次提高到合理的速度。在将代码复制回时,您可以对其进行重构,并尝试使函数主体简短而函数/形式/表达式简单(或分成几行)。


非常彻底的答案。也许其中一些建议作为“急救”是很好的,但是实际上,我们是否不希望Xcode能够简单地工作而不会经历巨大的麻烦?
mllm 2014年

1
不幸的是,xcode 6.1 + swift非常不稳定,因此需要这些“技巧”。苹果应该修复swift和xcode。但是swift非常适合编程,因此在短期内,这是阻止CPU使用率的唯一方法。
Daniel Unterberger 2014年

我做了您提议的所有可能的更改,但不幸的是,我的自动完成功能仍然很糟糕。我怀疑速记子句是否也会带来麻烦。有人可以承认吗?我的意思是返回(a == b)?x:y
Ilker Baltaci 2014年

好吧,以某种方式编写代码以使IDE开心是一种真正的废话
Andrey Gordeev,

10

因为Xcode的4自动完成被打破直到苹果决定来解决这个2岁的错误,唯一的解决办法,可惜,就是把代码完成关闭在Xcode的偏好(以下PIC的第一个选项)。

您可以通过键入CTRL spaceESC在需要时继续手动完成操作。

这是唯一适用于100%案例的解决方案。

在此处输入图片说明

我最近发现的另一件事是:如果在Xcode上使用插件,请不要使用。全部删除。他们使问题变得更糟。


5

您在使用Spotify吗?我在2009年中期的iMac(2.66Ghz)上安装了带有Xcode 6.1 GM的Yosemite GM并遇到了相同的问题。我发现一个名为“ SpotifyWebHelper”的进程始终被标记为没有响应,因此在Windows中禁用了“从网络启动”选项spotify,现在Xcode似乎运行得更好。


有趣,但对我而言,它与Spotify无关...但是它确实表明,这只是一个“常见”的性能问题-意味着-清除更多资源,它将更好地工作。真可悲,因为我没有更多资源可以提供(除了新Mac上的钱)。
mllm 2014年

2

我发现通常发生在以下情况:

  • 在单个语句中有长表达式(请参阅此答案
  • 在单个表达式中混合多个自定义运算符

第二种情况似乎已在最新的xcode版本之一中修复。示例:我定义了2个自定义运算符<&&>和<||>,并用在类似的表达式中a <&&> b <&&> c <||> d。拆分为多行解决了该问题:

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

我希望您的案件属于上述2个案件中的一个...请在任何一个案件中发表评论


5
不幸的是,它也发生在一个全新的干净项目中,其中没有任何内容,并且键入的内容很简单,例如“ var s:Stri ...”。我一开始输入St ...,就会在查找完成建议时变慢。
mllm 2014年

它绝对是我的操作数。同一行中有多个操作数会导致此错误。感谢你的回答。这应该是正确的答案
Kesava 2014年

2

即使在Xcode 6.3中,我也遇到了同样的问题

  • 超慢速自动完成
  • 超慢索引
  • swift和SourceKitService极大地占用了CPU
  • SourceKitService占用大量内存

即使在相对较小的项目中,所有这一切都在发生。我尝试了所有可以找到的修复:

  • 删除〜/ Library / Developer / Xcode / DerivedData / *
  • 删除〜/ Library / Caches / com.apple.dt.Xcode / *
  • 从代码中删除所有“ +”字符串组合
  • 删除了所有可疑的字典声明

这些都不对我的项目有实际帮助。

真正解决我问题的是:

  • 将每个类的每一端都放在自己的文件中
  • 将每个扩展名放在其自己的文件中(Class + ExtName.swift)
  • 在自己的文件中放置“类之外的swift方法”

现在,我的CPU使用率接近于零,内存使用率低,完成速度也很快。


2

通常,将缓存文件夹(DerivedData)移到SSD驱动器上(在我的情况下,具体来说是连接到Thunderbolt出口的外部存储器)已极大地提高了我的Xcode性能。.编译时间和对应用程序的一般怀疑速度大约快10倍。还将整个git文件夹移到了SSD上,极大地提高了git性能。


实际上,在最初的问题中,我已经用SSD驱动器升级了Mac,一切都包括在内。操作系统,仍然有问题
mllm

2

直到XCode 7.2才让我很痛苦。

苹果在XCode 7.3中修复了它,现在它就像一个魅力。它的运行速度非常快,而且功能更强大,因为它的工作方式似乎有点像文件的模糊搜索:您不必真正键入方法/属性的确切开头即可出现在命题列表中。


2

折叠所有方法会有所帮助。

command-alt-shift-left arrow可以解决问题...

折叠/展开当前方法或结构是否使用:

折叠:command-alt-左箭头

展开:command-alt-右箭头


1

SourceKitService处理代码中的注释也有点笨拙,并且嵌入的注释也会减慢它的速度。

因此,如果您有能力删除这样的大量嵌入式注释,则:

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

当然也可以提供帮助。


注意:在我的情况下,当文件具有大约700行带有嵌入式注释的注释时,实际上Xcode 7.3.1(7D1014)阻止了我键入任何字母。最初,我从该.swift文件中删除了该块,Xcode再次生效。我尝试通过删除嵌入的注释来部分地添加我的注释,但它仍然比平时慢,但是如果没有嵌入的注释,则显示出明显更好的性能。


1

我遇到同样的问题,即在特定的班级中打字滞后,结果是

/* Long multiline comments */

正在减慢打字速度。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.