提问者:小点点

访问Swift中作用域的“级别”以获得更有意义的调试字符串


我正在寻找一种动态确定代码执行范围的“级别”的方法。

例如,如果类z具有函数x和y:

如果函数x被类z调用,打印语句将显示为与从函数y内调用或从函数y内的函数内调用相同。

我希望在每个作用域的“级别”中包含额外的空白,这样当我打印以指示调用函数时,它打印的缩进比调用它的代码多一个选项卡。为此,我需要以某种方式确定范围的“级别”。我可以手动完成这项工作,但这将比它可能值得做的更痛苦。

Swift是否会在我可以访问的任何地方自动执行此操作?

编辑我刚刚意识到,从技术上讲,我要找的可能不是范围的“级别”,而是“被调用函数”的“级别”。比如,我想要一个值,它=1代表开始一个函数的每一个“{”,-=1代表结束一个函数的每一个“}”,如果这有意义的话,这样我就可以把一个“\t”乘以这个值,然后把结果放在该函数块中所有print语句的开头。


共2个答案

匿名用户

我认为没有任何内在的机制来满足你的需求。您可以加载堆栈跟踪并从中构建所需的内容,但这将是相当多的工作。

或者,您可以创建一个静态变量callDepth,在每个函数输入时递增,在每个函数结束时递减(或者在每个函数开始时定义的延迟块中递减),这样即使在函数的不同位置有返回语句,它也可以工作。)

然后,您可以使用callDepth变量来确定在记录函数数据时要使用多少选项卡。

匿名用户

对于任何寻找现成解决方案的人来说,以下是我所做的:

从很早的时候,我就有了每一个函数的第一行:

print("\t\(#function)  \(self.classForCoder)  \(#file.getLastPath())  \(Thread.current)")

这为我提供了有用的调试信息,这些信息缩进到更具体的打印调试语句之后。它也不需要根据功能进行定制,我只需复制/粘贴即可。根据上面接受的答案的输入来跟踪作用域,我制作了一个快速堆栈结构,仅用于跟踪函数名,并以关注作用域的方式打印它们:https://gist.github.com/austenstrine/38f27e32dc1248d16d44f1eac1af67d5

我使用该结构创建了一个静态变量:

class AppData //in a separate file
{
    static var funcStack = ScopedPrintableStack()
}

我使用堆栈的大小来确定print语句中的范围。现在,我在每个函数的顶部都有以下内容:

AppData.funcStack.push(#function)
print(String(repeating: "\t", count: AppData.funcStack.count)+"\(#function)  \(self.classForCoder)  \(#file.getLastPath())  \(Thread.current)")
defer {AppData.funcStack.popToss()}

项目级的查找和替换使得这很容易维护,只要我不触摸一个而不触摸它们。如果我稍后在项目范围内注释掉print语句以清理控制台,我仍然可以通过打印AppData.funcStack来访问函数范围层次结构。

另外,请注意。getLastPath()函数是String类的自定义扩展,因此我不必编写字符串(“foo/bar/some/Path.swift”.split(分隔符:“/”)。最后获取“Path.swift”