Xcode 10 - Instance will be immediately deallocated because property is 'weak'

Nader Besada picture Nader Besada · Aug 10, 2018 · Viewed 21.8k times · Source

I recently downloaded Xcode 10 and I noticed an apparent bug when using weak or unowned variables. I managed to create a simple example that showcases the problem so that people can recreate it.

class MainClass {
    weak var weakClass: SomeClass!

    init() {

        // WARNING: Instance will be immediately deallocated because property 'weakClass' is 'weak'

        self.weakClass = SomeClass()
    }
}

class SomeClass {}

As the error says, weakClass immediately deallocates once MainClass is initialized and is always nil.

I have opened up the same playground with Xcode 9.3 and I can confirm that the code works fine with no errors or warnings

Is this a bug in Xcode 10 or am I not getting something. If it is, is there any workarounds?

EDIT: Original Example

class LoginCoordinator {

    var viewModel: LoginViewModel?
    var viewController: LoginViewController?

    init() {
        viewModel = LoginViewModel()
        viewModel?.coordinator = self
        viewController = LoginViewController(viewModel: viewModel!)
    }
}


class LoginViewModel: ViewModelDelegate {
    weak var coordinator: LoginCoordinator?
}

coordinator is always nil in LoginViewModel

AppDelegate.swift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func setupView() {
        let coordinator = LoginCoordinator()
        let navigationController = UINavigationController(rootViewController: coordinator.create)

        navigationController.isNavigationBarHidden = true
        navigationController.navigationBar.isTranslucent = false

        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = navigationController
        window?.makeKeyAndVisible()
        window?.layer.cornerRadius = 6
        window?.layer.masksToBounds = true
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        setupView()
        return true
    }

Answer

vivekDas picture vivekDas · Aug 10, 2018

To understand this you must know the concept of ARC. ARC concept is automatic reference count means ARC will keep something in memory, as long as an allocated memory is strongly referenced by some variable. If it(ARC) found some allocated memory doesn't have any strong reference it will dealloc it. So the warning weakClass immediately deallocates once MainClass is initialized and is always nil. Because it doesn't have any strong reference.Please comment any doubt.

One example below for retain cycle creation:

class A {
var classBObject: B?

  init() {
     classBObject = B()
     classBObject.classAObject = self // Creates a retain cycle
 }
}

class B {
   var classAObject: A? // Strong(by default all are strong) variable create retain cycle
}

So, in class B if we take weak var classAObject retain cycle will not happen.