我有这种情况,我有一个静态变量,它会在应用程序的某个地方更改其值,从而导致错误。没有详细介绍代码。我需要知道是否有办法观察这个变量。因为在Xcode每次尝试观察一个变量时它会给我这个错误“错误:在这个框架中找不到名为'backend'的变量”。
所以我的问题是,是否有任何解决方法可以知道哪个地方确实改变了这个变量的值。
除了使用手表之外的其他任何东西,因为上述错误导致我因某些原因无法使用手表。
答案 0 :(得分:6)
您可以向变量(didSet
或willSet
)添加属性观察者,并在那里设置断点并在命中断点时查看帧,或者您可以记录当前堆栈跟踪当前线程。
对于第一个示例,在属性观察器中的一个简单断点,我已经设置了以下非常简单的类:
class Observable {
static var someProperty: String? {
willSet {
print("Some property will be set.")
}
didSet {
print("Some property has been set.")
}
}
}
使用断点:
我只是从单元测试中运行此代码,但您可以在任何地方获得相同的结果。这是我用以下代码触发更改的代码:
class ObservableTests: XCTestCase {
func testObservable() {
Observable.someProperty = "foo"
Observable.someProperty = "bar"
Observable.someProperty = "baz"
}
}
当代码运行时,我们将在断点处停在这里:
我特意将这个截图框架化了。我们看到绿线和蓝色箭头突出显示我们正在停止的断点,但是看左边。我们可以看到我们在哪个主题以及我们如何达到这个特定点。重要的是,我们可以在堆栈中向上和向下点击。
这里,堆栈中的大多数帧只向我们展示了无用的汇编代码。如果我们查看一个框架,这就是我们所看到的:
但是如果我们再增加一帧,我们就会找到修改变量的代码:
明确地说,我点击的部分跳转到代码的不同部分,这些部分导致设置此变量就在这里:
如上所述,打印堆栈跟踪也是一种选择,尽管它的效率要低得多。
如果我们将willSet
和didSet
更改为更像这样:
class Observable {
static var someProperty: String? {
willSet {
for symbol: String in NSThread.callStackSymbols() {
print(symbol)
}
}
didSet {
for symbol: String in NSThread.callStackSymbols() {
print(symbol)
}
}
}
}
然后我们将能够看到日志中打印的完整堆栈跟踪,如下所示:
以上屏幕截图中的兴趣点是这两个:
2 TTDSamplesTests 0x00000001087603fa _TFC15TTDSamplesTests15ObservableTests14testObservablefS0_FT_T_ + 74
3 TTDSamplesTests 0x0000000108760492 _TToFC15TTDSamplesTests15ObservableTests14testObservablefS0_FT_T_ + 34
很难解读,但你可以从中挑选出部分。
_TFC15的 TTDSamplesTests 强> 15的 ObservableTests 强> 14的 testObservable 强> fS0_FT_T _
答案 1 :(得分:0)
您可以做的一件事是用计算属性替换您的变量并在setter中设置断点:
class Foo {
static var bar:Int = 0
}
class FooToo {
static var _bar:Int = 0
static var bar:Int {
set {
// put break point here
print("FooToo bar is set")
FooToo._bar = bar
}
get {
return FooToo._bar
}
}
}
Foo.bar = 10
FooToo.bar = 10 // -> prints "FooToo bar is set"