2016-02-29 112 views
0

我有这种情况下,我有一个静态变量,它改变了它的价值在整个应用程序导致一个错误的价值。没有深入代码的细节。我需要知道是否有办法看这个变量。因为在Xcode上每次尝试观察一个变量,它都会给我这个错误“错误:在此帧中找不到名为'backend'的变量”。如何知道什么改变了变量值在xcode swift

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

除了使用手表以外的任何东西,因为由于某些原因,由于它不适用于我的上述错误。

+0

@DanBeaulieu是的,我使用断点,但在应用程序中有定时器,我已经在计时器内打印了此变量的值,并且由于某种原因,某些点的变量值随机变化。所以我需要知道它为什么被改变 –

+0

我想象一下手表只会告诉你你已经知道的东西:价值被改变了,但不是原因。尝试找到变量设置的所有位置,并添加断点或记录。 – deltab

回答

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 

这很难破译,但你可以选择它的部分。

_TFC15TTDSamplesTests15ObservableTests14testObservablefS0_FT_T_

  • 目标的我在跑这个代码名称为TTDSamplesTests
  • 该方法的的名称被称为ObservableTests
  • 方法的名称称为setter的名称为testObservable
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" 
+0

当一名物业观察员完成这项工作时,这是很多工作。 – nhgrif

+0

您也可以使用财产观察员来做这件事,是的。这两种方式都没有太多的工作。 – ColGraff