【发布时间】:2014-12-30 18:06:25
【问题描述】:
在对previous question 的回答中,我学会了如何有效地创建我将描述为缓存的单例对象:任何时候只有一个存在,但如果不需要它,它已被释放。
为了测试,我写了这个单元测试:
- (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"
);
}
问题是,最后一个断言失败了一半的时间。我在代码中的不同位置放置了NSLog() 调用,以确保实际上在释放其他两个引用之后分配了一个新对象。我唯一能猜到的是编译器注意到最近释放了一个大小合适的内存空间,因此决定使用它。即使我坚持代码尝试在两者之间分配其他东西,它仍然经常使用相同的内存地址。
有什么办法可以让它不这样做吗?或者,除了比较内存地址之外,是否有更好的方法来确保分配新对象?
【问题讨论】:
-
没有看到你如何实现
MyThing,没有人可以帮你解决问题。 -
@rmaddy 请参阅引用的previous question,尤其是this answer 以了解
MyThing的实现。 -
好的,你为什么关心下一个实例是否使用相同的地址?应该没关系。您确定在将
thing1和thing2设置为nil并再次重新分配thing1之间,此问题的代码中调用了dealloc? -
@rmaddy 这样我就可以测试了。是的。我只是追查了一堆在我的测试中保留并需要发布的地方。
-
但这不是一个有效的测试。如果一个对象被释放,然后创建了一个新对象,那么为新实例提供与先前释放的实例相同的内存地址是完全有效的。它仍然是一个新实例。
标签: objective-c memory memory-management singleton memory-address