Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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     } 
like image 431
Nader Avatar asked Aug 10 '18 05:08

Nader


2 Answers

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.

like image 107
vivekDas Avatar answered Sep 16 '22 17:09

vivekDas


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.

like image 24
ukim Avatar answered Sep 18 '22 17:09

ukim