0

Xcode debug shows the same variable twice on the "Variables View" after stops on the breakpoint. The variable has two values on the break point, but only one of the values is valid on the code. For instance the case of the picture below, the real value is nil, however it shows some date.

Is that a bug on Xcode ? or, we can configure Xcode to display the variables in a better way?

enter image description here

I have found that other question https://stackoverflow.com/a/53135368/4307080 , however the folder ~/Library/Developer/Xcode/UserData/Debugger/ does seem to exist anymore on Xcode 14+, therefore I couldn't test that.

That is happening on a function

internal func bindErrorStream(from service: ErrorStreamProvider) {
    service
      .errorStream
      .receive(on: DispatchQueue.background)
      .sink { [weak self] error in
        guard let self else { return }
        
        switch error.cause {
        case .invalidAppVersion:
          self.versionState.value = AppState.Version(isForbidden: true)
          
        case .serviceUnavailable(let retryAfterDate):
          if let retryAfterDate {
            self.apiStatus.value = AppState.APIStatus.undergoingMaintenance(until: retryAfterDate)
          } else {
            self.apiStatus.value = AppState.APIStatus.unavailable
          }
          
          self.scheduleApiStatusReset()
          
        default: break
        }
      }
      .store(in: &disposables)
  }

If you try to frame the local variables, you can see that is not a simple scope problem.

(lldb) fr variable -a -F -L
/// ....

0x000000016b6f5b20: retryAfterDate = nil
0x000000016b6f5d50: retryAfterDate = 2001-01-01 00:00:00 UTC
HangarRash
  • 7,314
  • 5
  • 5
  • 32

1 Answers1

0

Code like:

.sink { [weak self] error in
    guard let self else { return }

has two variables named self. There's the weak self from the closure and then there's the new self local variable from the guard let.

The variable view is showing an optional Core.ErrorStreamProcessor and a non-optional Core.ErrorStreamProcessor reflecting those two self variables.

The lines:

case .serviceUnavailable(let retryAfterDate):
    if let retryAfterDate {

define two separate retryAfterDate variables. There's the one from the associated value of the case and then there's the one declared as a local variable inside the if let statement.

HangarRash
  • 7,314
  • 5
  • 5
  • 32