Variable being retained in unit test

I'm having an interesting issue with unit testing a memory leak. I don't understand why the test fails when the line "context!.getView()" is uncommented, but we're suspecting it's a language intern issue. We can make the test pass as expected using an autorelease pool, but I don't understand the root cause of the problem.

The test:
Code Block
class MemoryLeakTests: XCTestCase {
func testExample() throws {
var view:MockView? = MockView()
weak var weakRefToView = view
var context: SomeContext? = SomeContext()
context!.setView(view!)
/*
Uncomment this and it fails 🤷‍♂️🤷‍♂️🤷‍♂️🤷‍♂️
context!.getView()
*/
view = nil
XCTAssertNil(weakRefToView)
}
}


Code Block
@interface SomeContext : NSObject
- (MockView *) getView;
- (void) setView: (MockView*) view;
@end


Code Block
#import "SomeContext.h"
@implementation SomeContext {
__weak MockView* _view;
}
- (MockView*) getView {
return _view;
}
- (void) setView: (MockView*) view {
_view = view;
}
@end


Code Block
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface MockView : NSObject
@end
NS_ASSUME_NONNULL_END


Code Block
#import "MockView.h"
@implementation MockView
@end

We can make the test pass as expected using an autorelease pool

This doesn’t strike me as strange. ARC, as implemented by both Swift and Objective-C, may end up putting references to an object into the autorelease pool. If that happens, you won’t see that object deallocated until the autorelease pool is drained. In an XCTestCase method, the autorelease pool isn’t drained until return back into the XCTest infrastructure. If your unit test needs it to drain earlier, bracket that code with autoreleasepool { … }.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@apple.com"
Variable being retained in unit test
 
 
Q