Swift 5.10: Cannot access property '*' with a non-sendable type '*' from non-isolated deinit; this is an error in Swift 6

The following Swift UIKit code produces the warning "Cannot access property 'authController' with a non-sendable type 'AuthController' from non-isolated deinit; this is an error in Swift 6":

import UIKit

class AuthFormNavC: UINavigationController {
    let authController: AuthController

    init(authController: AuthController) {
        self.authController = authController
        super.init(rootViewController: ConsentVC())
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        authController.signInAnonymouslyIfNecessary()
    }
}

Swift 5.10, Xcode 15.3 with complete strict concurrency checking.

What is the workaround?

Please don't ask me why I'm doing what I'm doing or anything unrelated to the question.

If you're wondering why I want to call authController.signInAnonymouslyIfNecessary() when the navigation controller is denitialized, my goal is to call it when the navigation controller is dismissed (or popped), and I think that the deinitializer of a view controller is the only method that is called if and only if the view controller is being dismissed (or popped) in my case. I tried observing variables like isViewLoaded in the past using KVO but I couldn't get it to work passing any combination of options in observe(_:options:changeHandler:).

Accepted Reply

https://stackoverflow.com/questions/78284030/swift-5-10-cannot-access-property-with-a-non-sendable-type-from-non-iso/78285030#78285030

In a nutshell: call signInAnonymouslyIfNecessary() in viewDidDisappear(): avoid in general dealing with class deinitializers.

But if you insist on calling signInAnonymouslyIfNecessary() in the deinitializer, you can:

  • Mark AuthController as @MainActor
  • Mark signInAnonymouslyIfNecessary as nonisolated
  • Wrap signInAnonymouslyIfNecessary in a Task:
@MainActor final class AuthController {
    nonisolated func signInAnonymouslyIfNecessary() {
        Task { @MainActor in
            /// ...
        }
    }
}

Replies

https://stackoverflow.com/questions/78284030/swift-5-10-cannot-access-property-with-a-non-sendable-type-from-non-iso/78285030#78285030

In a nutshell: call signInAnonymouslyIfNecessary() in viewDidDisappear(): avoid in general dealing with class deinitializers.

But if you insist on calling signInAnonymouslyIfNecessary() in the deinitializer, you can:

  • Mark AuthController as @MainActor
  • Mark signInAnonymouslyIfNecessary as nonisolated
  • Wrap signInAnonymouslyIfNecessary in a Task:
@MainActor final class AuthController {
    nonisolated func signInAnonymouslyIfNecessary() {
        Task { @MainActor in
            /// ...
        }
    }
}