我在输入一些“简单”代码时也体验到了 100% 以上的 CPU。通过构建代码的方式使 swift-parser 更快的一些小技巧。
不要在字符串中使用“+”连接符。对我来说,这很快就会触发缓慢。
每个新的“+”都会使解析器陷入困境,每次您在函数体的某处添加新字符时,它都必须重新解析代码。
代替:
var str = "This" + String(myArray.count) + " is " + String(someVar)
使用在 swift 中解析似乎更有效的模板语法:
var str = "This \(myArray.count) is \(someVar)"
这样我基本上注意到 strlen 没有限制 inline vars "\(*)" 。
如果你有计算,使用 + / * - 然后将它们分成更小的部分。
代替:
var result = pi * 2 * radius
使用:
var result = pi * 2
result *= radius
它可能看起来效率较低,但这样的 swift 解析器要快得多。
如果某些公式需要进行许多操作,即使它们在数学上是正确的,它们也无法编译。
如果你有一些复杂的计算,那么把它放在一个函数中。这样,解析器可以解析一次,而不必在每次更改函数体中的某些内容时重新解析它。
因为如果你的函数体中有一个计算,那么 swift 解析器每次都会检查它,如果类型、语法等仍然正确。如果计算上方的行发生更改,则计算/公式中的某些变量可能已更改。如果你把它放在一个外部函数中,那么它将被验证一次,并且 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 仍然有很多 bug,但是如果你遵循这些简单的技巧,编辑代码就会再次变得可以接受。我更喜欢 swift,因为它摆脱了 .h 文件并使用更简洁的语法。仍然需要许多类型转换,例如 "myVar as AnyObject" ,但与复杂的 Objective-C 项目结构和语法相比,这是较小的邪恶。
还有另一种体验,我尝试了 SpriteKit,它使用起来很有趣,但如果你不需要以 60 fps 的速度不断重绘,它的效率就很低了。如果您的“精灵”不经常更改,则使用旧的 CALayers 对 CPU 来说要好得多。如果您不更改图层的 .contents,则 CPU 基本上处于空闲状态,但如果您在后台运行 SpriteKit 应用程序,则由于硬限制 60fps 更新循环,其他应用程序中的视频播放可能会开始卡顿。
有时 xcode 在编译时显示奇怪的错误,然后进入菜单“Product > Clean”并再次编译它会有所帮助,这似乎是缓存的错误实现。
在另一个 stackoverflow 帖子 here 中提到了当 xcode 卡在您的代码中时改进解析的另一种好方法。基本上,您将 .swift 文件中的所有内容复制到外部编辑器中,然后逐个函数将其复制回来,看看您的瓶颈在哪里。在我的项目因 100% CPU 而疯狂之后,这实际上帮助我让 xcode 再次达到合理的速度。在将代码复制回来时,您可以对其进行重构并尝试保持函数体简短且函数/公式/表达式简单(或分成几行)。