【问题标题】:Can you decorate a debug-breaking function to instead break where that function is called from?你可以装饰一个调试中断函数来中断调用该函数的位置吗?
【发布时间】:2018-10-14 08:20:50
【问题描述】:

最好用一个例子来解释。考虑这个mustOverride 辅助函数:

func mustOverride(callSite:String = #function) -> Never {
    preconditionFailure("\(callSite) must be overridden in a subclass")
}

我们用它来制作虚假的抽象类,如下所示:

// Faux 'abstract' class
class SoundBase {

    func play(){
        mustOverride()
    }
}

// 'Concrete' class
class CatSound : SoundBase {

    override func play(){
        // play cat 'meow' sound
    }
}

通过上述方式,如果您直接实例化SoundBase 并调用play(),您将触发mustOverride() 函数,该函数在可调试状态下中断。问题是它在mustOverride() 函数内部中断,而不是在调用站点play()

Microsoft 的 .NET 有一个简洁的功能,您可以使用属性装饰函数以更改它们与调试器的交互方式(see here 了解更多信息)。

例如,它们有一个DebuggerHidden 属性,如果将其应用于mustOverride(),将导致调试器改为在调用play() 函数内部中断,而mustOverride() 内部中断为您节省了不必要的调用堆栈之旅,只是为了备份一个级别以找出错误的真正位置。

我想知道 Swift 是否有类似的功能。使用得当真的很棒。

【问题讨论】:

  • 我假设在 mustOverride() 中抛出错误并在 play() 中捕获它不适用于您的情况?
  • 不,这与错误或在运行时捕获它无关。这是关于调试时的调用堆栈,并且希望始终忽略最后一帧并转到前一帧。希望这是有道理的。

标签: swift debugging swift4 callstack


【解决方案1】:

假设您在 Xcode 中进行调试,您正在寻找的是 @_transparent 属性。它在行动中:

@_transparent
func mustOverride(callSite: String = #function) -> Never {
    preconditionFailure("\(callSite) must be overridden in a subclass")
}

class SoundBase {
    func play(){
        mustOverride()
    }
}

class CatSound: SoundBase {
    override func play() {}
}

SoundBase().play()

结果:

来自文档:

在语义上,@_transparent 的意思类似于“将此操作视为原始操作”。该名称旨在暗示编译器和已编译程序都将“看穿”操作对其实现。

注意:

  • 由于@_transparent以下划线开头,以后可能会改变

【讨论】:

  • 有趣。这里(来自文档)显然有很多其他规则(来自文档)可能会在某些情况下使其无法使用,但我认为这是我将要达到的最接近的目标.我会让这个开放时间更长一点,看看是否有人提出更好/更接近的东西,但如果没有,我会将此标记为答案。谢谢!
猜你喜欢
  • 1970-01-01
  • 2014-02-04
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 2011-03-06
  • 1970-01-01
  • 2012-08-18
相关资源
最近更新 更多