我有一个小的值类,我创建了很多实例。通常具有相同的值。此类用作一种标识符,因此主要用途是将此类的实例相互比较(通过isEqual:
)。
为了节省一些内存和比较时间,我只在 a 中保留唯一实例NSHashTable
并使用指针比较而不是isEqual:
.
所以我指定的初始化程序如下所示:
- initWithStuff: (NSString *)stuff;
{
self = [super init];
if (!self) return nil;
// ... (actual initialisation code omitted)
hash = UniquingHashTable();
static OSSpinLock spinlock = OS_SPINLOCK_INIT;
OSSpinLockLock( &spinlock );
id member = [hash member: self];
if (member) self = member;
else [hash addObject: self];
OSSpinLockUnlock( &spinlock );
return self;
}
UniquingHashTable()
如果它尚不存在,则返回全局NSHashTable
或通过创建它。[NSHashTable weakObjectsHashTable]
这weakObjectsHashTable
是重要的一点 - 它存储指向对象的弱指针,一旦没有对该对象的其他强引用,这些对象就会自动被删除。初始化是线程安全的,这要归功于dispatch_once
.
这很好用,峰值内存使用率显着降低,我所有的测试用例仍然通过。但我不太确定是否可以依靠指针比较来测试是否相等。是否存在我同时获得两个不同实例的情况或竞争条件(因此指针不同)但它们仍然比较相等isEqual:
?
澄清我有/想要什么:
给定
MyClass *a = [[MyClass alloc] initWithStuff: stringA];
MyClass *b = [[MyClass alloc] initWithStuff: stringB];
我们总是有
[a isEqual: b] == [stringA isEqual: stringB];
新代码不会改变这一点。
我想要实现的是
[a isEqual: b] == (a == b)
这样我就可以用isEqual:
更快的指针比较替换 。(是的,我测量了这个,这将很重要)。
对于单线程代码,或者如果我使用的是 aNSMutableSet
而不是弱的,NSHashTable
这总是可行的。我只是不确定是否有任何竞争条件,以便我可以有这样的情况
[a isEqual: b] && (a != b)
是真的。