Xcode 6.1中内置的Swift REPL不能检查和操作您运行的应用程序,无法正常工作。

7

Xcode 6.1的更新之一是:

Swift REPL内置于Xcode调试器,可以检查和操作运行中的应用程序

我创建了一个空项目,在viewDidLoad函数中设置了断点。当应用程序停在断点处时,在Xcode控制台中键入“repl”,然后尝试使用print self打印。

println(self)

但是Xcode给我报错:

错误:未解析的标识符'self'

但是它不起作用。

问题是:我做错了什么?

1个回答

18
原来在lldb中,Swift有两个表达式求值器——repl和普通的expression命令。这两者有重要区别。 repl命令将代码评估为如果输入到新的Swift模块文件并导入到当前运行的应用程序中,那么常规的Swift编译器也会这样做。事实上,每次调用repl都会向这样一个模块添加代码,并且repl添加了一些强大的功能,例如能够重新定义Swift编译器不允许的类等。因此,它最适合定义全新的类、函数等。让repl使用这个全局上下文也是必要的,因为Swift中的某些定义只能在模块级别进行,repl使您可以访问语言的所有这些特性。然而,由于这意味着repl命令几乎按定义没有进入repl命令运行的上下文中的可见性。 expression命令将代码评估为在当前停止的函数上下文中运行的代码。这很有用,因为它使您可以访问ivars和局部变量,并真正像可能在该特定上下文中的代码一样运行。但执行这个技巧的副作用是它不能完全像创建一个新模块一样,这就是repl应该模拟的。请注意,您无法在expr中执行的事情相当神秘,您通常可以通过在expression命令中构建临时类等来逃避这些问题。您要使用expr来运行您的println(self)命令。
简而言之,如果您想在调试过程中创造新类等,请使用repl命令,但是如果您想访问局部变量等,请使用expr

需要注意的是,repl实际上是expr的一种变体。如果查看lldb中关于repl的帮助,它会告诉你该命令是expression -r --的别名。有些人还使用另一个别名:print,即expression --。这个别名在输入真正的命令表达式时非常方便,因为它可以关闭选项解析...


非常好的解释,谢谢。您认为在未来的版本中能否访问REPL中的局部变量呢? - Kostiantyn Koval
我无法预见。 - Jim Ingham
是的,我还没有看到任何真正令人信服的理由可以将REPL和debuggee命名空间合并,这种混淆命名的潜在影响远大于合并的好处。 - Jim Ingham

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接