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

instance will be immediately deallocated because property is weak iboutlet
instance will be immediately deallocated because property adview is weak
weak swift

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
    }

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.

Instance will be immediately deallocated becaus |Apple Developer , following code worked fine with Xcode 9 and swift 4.2: class Instance will be immediately deallocated because property 'vc' is 'weak' Is it ok to use a weak variable in the next line, ten line below, two screens below,  In the first case the compiler can see that the result of an allocation is being assigned to a weak property and warn you that it will be immediately released, which is probably not what you want. In the second case it sees the assignment to a local variable and so the object will remain in memory for some time.

This is the purpose of weak. Swift uses reference count to manage memory. A strong pointer increases the reference count of the pointed object by 1, a weak pointer does not increase reference count. An object with 0 reference count will be deallocated.

Your instance of SomeClass only pointed by a weak pointer, so its reference count is 0. As a result it is deallocated immediately.

Weak is useful to avoid retain cycles. For example, in escaping closure and in delegation design pattern.

"Instance will be immediately deallocated" warning in Xcode when , weak var weakClass: SomeClass! init() // WARNING: Instance will be immediately deallocated because property 'weakClass' is 'weak' self. 11 Xcode 10 - Instance will be immediately deallocated because property is 'weak' Aug 10 '18 6 trying to detect iphone x in swift always return false Aug 4 '18 6 Invalid App Store Icon Jul 30 '18

The question is, "is that reference strongly referenced elsewhere? If so, it will not be deallocated."

I propose that Apple's warning message is misleading. I think that it should state that it will be deallocated immediately when its containing object is deallocated or when other strong references to it are deallocated.

Here's why.

We have this warning on an instance in a view controller and the weak var is not deallocated immediately. The view controller appears, the weak var is instantiated, we wait, click a button that hits a breakpoint and yup, the weak var is still not nil. Yet when the view controller disappears and is deallocated, the weak var is deallocated immediately.

But why? Well, by the time we come the part of code that has a weak reference to the variable, other code has already has a retain count of 3 and even though it's weak, it can't be immediately dismissed.

You can check this with po myObject.retainCount. It's not guaranteed to be accurate, but it will give you an idea. If the object's retaincount > 1 and it's strongly linked somewhere else, (please put a comment in your code to indicate where it is strongly referenced), weak will work. To avoid a compiler warning, don't reference the object directly, but the strong reference in the other object.

So, I think that Apple needs to reword this warning because it's surely misleading.

Weak property deallocation confusion, But Xcode (Xcode 10 beta) gives me a warning saying: Instance will be immediately deallocated because property 'delegate' is 'weak'. Clicking  There does seem to be an Instance will be immediately deallocated because property 'presentationContextProvider' is 'weak’ warning but I’ve added @State var session: ASWebAuthenticationSession? as a property of the struct and it’s still there (and I’m still getting the error).

9 Notes for me in March Swift 4.2, for a test, you can run in Postman or in your GitHub click "Raw" in a file in repo and copy the link 2. If you found an error "Instance will be immediately deallocated because property 'dataSource' is 'weak'" cornerRadius = 10 this has the effect of making Xcode convert it to @2x and @3x at build time. 5 Xcode 10 - Instance will be immediately deallocated because property is 'weak' Aug 10 '18

Instance will be immediately deallocated because property, This function in TableViewIndex open override func prepareForInterfaceBuilder() { dataSource = TableDataSource() } throws a warning in Swift  This is a slight improvement over a bare search, but it returns all references, not just the particular one you're looking for. For instance, if you have a class with a "height" property, searching for symbol references on your height property will return references to all kinds of other height properties you used, so you still have to sift through the results to find the ones you want.

Weak property deallocation confusion, But Xcode (Xcode 10 beta) gives me a warning saying: Instance will be immediately deallocated because property 'delegate' is 'weak'. Clicking  Xcode 10.1 beta 2 and later support UI testing with devices running beta versions of iOS 12. (43796360) Fixed an issue where the test Bundle Did Finish(_:) method wouldn't be called on an observer added to the shared XCTest Observation Center instance if the observer was added at any point after testing had already started.

Comments
  • Its not a bug. Swift Playground may temporarily retain the object while it executes as it keeps track of it whereas there is nothing to retain your object when you run it your coordinator/controller.
  • I ran the code normally outside playgrounds and it is still not working @ekscrypto
  • Exactly, just remove "weak", code should work.
  • @NaderBesada why don't you create a temp deinit method for LoginCoordinator and print out a message indicating it's been hit (or set a breakpoint). It would appear from what you describe that LoginCoordinator is weakly held. Where is LoginCoordinator created?
  • LoginCoordinator is initally created in the AppDelegate's didFinishLaunch
  • Makes sense. In my original code, SomeClass is a UIViewController with a strong reference to MainClass. So for MainClass to have a reference to SomeClass, SomeClass` has to be a weak variable in order to avoid a retain cycle, correct?
  • In your code provided above I can't see SomeClass with a strong reference to MainClass ?
  • If I add let mainClass = MainClass() to SomeClass wouldn't that create a retain cycle? I tried that and the warning is still there
  • @NaderBesada A retain cycle is created when two objects have strong pointers pointed to each other. An object is an instance of a class.
  • @NaderBesada based on the way you are doing things, you should make MainClass hold a strong ref to SomeClass and have SomeClass hold a weak to MainClass. One way of thinking about it is that in your example code, MainClass is allocating SomeClass, so it should hold the strong ref.
  • I edited my answer to illustrate my problem in a better way @MobileBen
  • Define immediately. We have this warning on an instance in a view controller and the weak var is not deallocated immediately. The view controller appears, the weak var is instantiated, we wait, click a button that hits a breakpoint and yup, the weak var is still not nil. So, define immediately, because this weak var is not deallocated immediately.