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.