如何知道xcode swift

时间:2016-02-29 01:41:35

标签: xcode swift debugging

我有这种情况,我有一个静态变量,它会在应用程序的某个地方更改其值,从而导致错误。没有详细介绍代码。我需要知道是否有办法观察这个变量。因为在Xcode每次尝试观察一个变量时它会给我这个错误“错误:在这个框架中找不到名为'backend'的变量”。

所以我的问题是,是否有任何解决方法可以知道哪个地方确实改变了这个变量的值。

除了使用手表之外的其他任何东西,因为上述错误导致我因某些原因无法使用手表。

2 个答案:

答案 0 :(得分:6)

您可以向变量(didSetwillSet)添加属性观察者,并在那里设置断点并在命中断点时查看帧,或者您可以记录当前堆栈跟踪当前线程。

对于第一个示例,在属性观察器中的一个简单断点,我已经设置了以下非常简单的类:

class Observable {
    static var someProperty: String? {
        willSet {
            print("Some property will be set.")
        }
        didSet {
            print("Some property has been set.")
        }
    }
}

使用断点:

enter image description here

我只是从单元测试中运行此代码,但您可以在任何地方获得相同的结果。这是我用以下代码触发更改的代码:

class ObservableTests: XCTestCase {
    func testObservable() {
        Observable.someProperty = "foo"
        Observable.someProperty = "bar"
        Observable.someProperty = "baz"
    }
}

当代码运行时,我们将在断点处停在这里:

enter image description here

我特意将这个截图框架化了。我们看到绿线和蓝色箭头突出显示我们正在停止的断点,但是看左边。我们可以看到我们在哪个主题以及我们如何达到这个特定点。重要的是,我们可以在堆栈中向上和向下点击。

这里,堆栈中的大多数帧只向我们展示了无用的汇编代码。如果我们查看一个框架,这就是我们所看到的:

enter image description here

但是如果我们再增加一帧,我们就会找到修改变量的代码:

enter image description here

明确地说,我点击的部分跳转到代码的不同部分,这些部分导致设置此变量就在这里:

enter image description here

如上所述,打印堆栈跟踪也是一种选择,尽管它的效率要低得多。

如果我们将willSetdidSet更改为更像这样:

class Observable {
    static var someProperty: String? {
        willSet {
            for symbol: String in NSThread.callStackSymbols() {
                print(symbol)
            }
        }
        didSet {
            for symbol: String in NSThread.callStackSymbols() {
                print(symbol)
            }
        }
    }
}

然后我们将能够看到日志中打印的完整堆栈跟踪,如下所示:

enter image description here

以上屏幕截图中的兴趣点是这两个:

2   TTDSamplesTests                     0x00000001087603fa _TFC15TTDSamplesTests15ObservableTests14testObservablefS0_FT_T_ + 74
3   TTDSamplesTests                     0x0000000108760492 _TToFC15TTDSamplesTests15ObservableTests14testObservablefS0_FT_T_ + 34

很难解读,但你可以从中挑选出部分。

  

_TFC15的 TTDSamplesTests 15的 ObservableTests 14的 testObservable fS0_FT_T _

  • 我运行此代码的目标的名称是 TTDSamplesTests
  • 该方法所在的的名称称为 ObservableTests
  • 调用setter的方法的名称称为 testObservable

答案 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"