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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With