dannys42
(Danny Sung)
1
I've got a class that initializes some blocks and such, and want to ensure I don't have any retain cycles. I'm attempting to write a unit test to verify some simple cases, like this:
func testThat_MyClass_WillRelease() {
weak var myClass = MyClass()
XCTAssertNil(myClass)
}
For many cases this seems to work, but I've encountered a class where this doesn't work. When I add some prints around the deinit calls like this:
class MyClass {
deinit {
print("MyClass: deinit")
}
}
func testThat_MyClass_WillRelease() {
weak var myClass = MyClass()
print("Checking for nil")
XCTAssertNil(myClass)
}
What I'm seeing in the output is not in the order I expect:
Checking for nil
MyClass: deinit
So this explains why my test assertion is failing. But I don't understand why this is happening.
I've tried doing a few things to force an out-of-scope call to deinit, but nothing seems to work...
- Wrapping in
do {} or a function call:
func testThat_MyClass_WillRelease() {
weak var myClass: MyClass?
do {
myClass = MyClass()
}
XCTAssertNil(myClass)
}
- Wrapping in
autoreleasepool {}
func testThat_MyClass_WillRelease() {
weak var myClass: MyClass?
autoreleasepool {
myClass = MyClass()
}
XCTAssertNil(myClass)
}
I've tried other more complicated things as well. What am I missing? Is there a better way to write a unit test like this?
Thanks
eskimo
(Quinn “The Eskimo!”)
2
What I'm seeing in the output is not in the order I expect:
I tested this (with Xcode 15.4) and it didn’t reproduce for me. However, I do have a suggestion for how to investigate: Set a breakpoint on the print(…) call in your deinitialiser and look at the backtrace to see where that last ref is being released.
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
1 Like
vns
3
What if instead of weak reference, use checking references count from Foundation of ˋisKnownUniquelyReferenced` from Swift stdlib? That seems to be more obvious (from reader perspective) and determined way to test, since in test case there should be only one reference to the instance.
1 Like
tera
4
Is that an NSObject subclass?