In the answers to a previous question, I learned how to effectively create what I would describe as a cached singleton object: There is only one present at any one time, but if it's not needed, it's deallocated.
In order to test it, I wrote this unit test:
- (void)testThingInstance {
MyThing *thing1 = [MyThing new];
MyThing *thing2 = [MyThing new];
XCTAssertEqual(thing1, thing2, @"Should have single thing");
// Let's release the thing, but keep its address.
uintptr_t pointer_as_integer = (uintptr_t)thing1;
thing1 = thing2 = nil;
// Now get a new thing. It should be a brand new object.
thing1 = [MyThing new];
XCTAssertNotEqual(
(uintptr_t)thing1, pointer_as_integer,
@"Should have a new thing, not a permanent singleton"
);
}
The trouble is, it fails that last assertion fails half the time. I put NSLog()
calls in various places in my code to make sure that a new object was, in fact, allocated after the other two references were released. The only thing I can guess is that the compiler is noticing that a memory space just the right size was recently freed and so decides to make use of it. Even when I stick in code to try to allocate something else in between, it still often uses the same memory address.
Is there any way I can get it not to do that? Or, preferably, might there be a better way to make sure that a new object is allocated other than comparing memory addresses?