Reputation: 123
I have defined a class called Person
. This is my code:
class Person {
var closure: (() -> ())?
var name: String
init(name: String) {
self.name = name
print("\(name) is being initialized")
}
deinit {
print("\(name) is being deinitialized")
}
}
then I use Person
in class called ViewController
:
class ViewController: UIViewController {
var person = Person(name: "john")
let aStr = "john is a cute boy"
override func viewDidLoad() {
super.viewDidLoad()
person.closure = {
print("\(self.aStr)")
}
person.closure!()
}
}
In my opinion, the picture of memory about my code like this :
So, from above picture, in my opinion, it will cause strong reference cycle between the three instances, but I can not get any leak from Instruments
, so I have some confusion.
Does this code cause strong reference cycle?
If not, when will ARC deallocate the instance of Person
? the method named deinit
in Person
class is never called.
Upvotes: 3
Views: 1035
Reputation: 1615
Yes, this's a typical retain cycle.
To solve this problem use [weak self]
in your closure
person.closure = { [weak self] in
guard let strongSelf = self else { return }
print("\(strongSelf.aStr)")
}
To really create a leak.
I create a demo App. Root is a navController.
The navController has a root controller. Let's call it buttonController.
When you click button in the buttonController, it create your ViewController and push to navController.
When you click back button in navigation bar, the navController pop your ViewController instance.
Profile it, then you will see the leak and the retain cycle in Instruments.
Xcode default template of iOS App use a single page, which always retain your ViewController instance. If the ViewController instance is still used by the system, it's actually not a leak yet. So push & pop show that leak for you.
Upvotes: 2