当前位置: 首页 > 知识库问答 >
问题:

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

干善
2023-03-14

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

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

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

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

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

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

共有2个答案

钱浩荡
2023-03-14

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

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

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”

段曦
2023-03-14

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

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

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

 类似资料:
  • 问题内容: 我想问一下在调试过程中是否有可能以更有意义的方式识别对象。例如现在在Flex Builder调试面板中,例如: 对象(@ 12131241241) 理想情况下,我想拥有Object(@“ field1:field2”)…可以做到这一点。我相信在Java中,可以通过重写给定类的toString方法来实现…。在as3中尝试相同,但没有用 问题答案: 这里没有直接回答您的问题,但是周围有许多

  • 问题内容: 我目前正在从objc.io 阅读出色的 Advanced Swift 书籍,并且遇到了一些我不理解的问题。 如果在操场上运行以下代码,您会注意到,修改词典中包含的结构时,下标访问权限会创建一个副本,但是看起来词典中的原始值已被副本替换。我不明白为什么。到底是什么情况? 另外,有没有办法避免复制?据这本书的作者说,没有,但我只是想确定一下。 问题答案: dict[“key”]?.chan

  • 问题内容: 我的文件中有一个Python脚本,运行该脚本仅需30多秒钟。我想对此进行简要介绍,因为我希望大幅减少这次的时间。 我正在尝试使用来分析脚本,但实际上似乎告诉我的是,是的,主脚本运行了很长时间,但没有给出我期望的细分。在终端上,我输入如下内容: 我得到的结果是: 这似乎并没有告诉我任何有用的信息。绝大多数时间被简单地列出为: 在中,第18行只不过是关闭文件标题块注释而已,因此,并不是把全

  • 问题内容: 我正在寻找访问指令中“父”范围的任何方式。范围,超越,要求,从上方传入变量(或范围本身)的任何组合,等等。我完全愿意向后弯腰,但我想避免某些完全不可靠或难以维护的事情。例如,我知道我现在可以通过从preLink参数中获取并对其范围进行迭代以找到概念上的“父级” 来做到这一点。 重要说明 是,该指令必须在同一父范围内可重用。因此,默认行为(作用域:false)对我不起作用。我需要为指令的

  • 问题内容: 我想实现一个单独的ErrorHandler类,该类在某些事件上显示错误消息。该类的行为应从其他不同的类中调用。发生错误时,它将有一个as输出。此AlertView的显示应始终位于顶部。因此,无论从何处引发错误,最顶层的viewController都应显示AlertMessage(例如,当异步后台进程失败时,无论在前台显示什么视图,我都将收到一条错误消息)。 我发现一些要点似乎可以解决我

  • 如何更改blob访问策略? 目前,我可以使用azure quick Start创建一些测试blob。这很好用,但在我的例子中,Blob的公共访问级别默认为private。我想将公共访问级别从Private(无匿名访问)设置为Blob(仅对Blob进行匿名读取访问)。 当我运行这段代码时,它将引发以下异常,我认为这是因为没有正确设置。 异常StackTrace: 通过一些代码示例向我解释如何为Blo