Iphone 尝试将对象添加到MutableOrderedSet时,IsEqual方法发送到解除分配的实例

Iphone 尝试将对象添加到MutableOrderedSet时,IsEqual方法发送到解除分配的实例,iphone,objective-c,ios,nsmutableset,Iphone,Objective C,Ios,Nsmutableset,我有一个NSMutableOrdered集合,它包含两种类型的对象(我创建的),即片段和其他 Piece和Other都覆盖了它们的isEqual方法,如下所示: 作品: - (BOOL)isEqual:(Piece *)object { if (([title isEqualToString:[object title]]) && ([composer isEqualToString:[object composer]]) &&am

我有一个NSMutableOrdered集合,它包含两种类型的对象(我创建的),即片段和其他

Piece和Other都覆盖了它们的isEqual方法,如下所示:

作品:

- (BOOL)isEqual:(Piece *)object
{
    if (([title isEqualToString:[object title]])
        && ([composer isEqualToString:[object composer]])
        && (major == [object major])
        && (tempo == [object tempo])
        && (pieceKey == [object pieceKey])
        && (pieceTime == [object pieceTime]))
        return YES;
    else 
        return NO;
}
其他:

- (BOOL)isEqual:(Other *)object
{
    if (([title isEqualToString:[object title]])
        && ([subTitle isEqualToString:[object subTitle]])
        && ([description isEqualToString:[object description]])
        && (otherTime == [object otherTime]))
        return YES;
    else 
        return NO;
}  
我还重写了这两个类的散列,为每个实例创建一个唯一的散列(通过获取ivar的int值并添加它们)

在我的应用程序中,从集合中删除另一个,然后当我尝试向集合中添加一个片段时,我得到以下结果:

-[Other isEqual:]: message sent to deallocated instance 0x80d5680
以下是哈希方法:

- (NSUInteger)hash
{
    NSUInteger prime = 31;
    NSUInteger result = 1;
    result = prime * (result + [title intValue]);
    result = prime * (result + [composer intValue]);
    result = prime * (result + major);
    result = prime * (result + tempo);
    result = prime * (result + pieceKey);
    result = prime * (result + pieceTime);
    return result;
}
如果有人知道为什么会这样,我真的会帮上忙


谢谢,

我相信isEqual是集合比较的一部分,因为集合是一组独特的项目。也许您应该在从旧集合中删除成员之前将其添加到新集合中


希望这有帮助

这不是一个真正的答案,但它将帮助我们找到问题所在。一些问题:

  • 您确定0x80d5680是以前删除的实例吗
  • 如何将其从集合中移除
  • 添加对象后是否修改对象的状态
  • 您确定您的哈希是唯一的(ivars的int值之和听起来可疑)
最后,确保对象遵守以下规则:

如果两个对象相等,则它们必须具有相同的哈希值。如果在子类中定义isEqual:并打算将该子类的实例放入集合中,那么最后一点尤为重要。确保在子类中也定义了hash


有关更多信息,请参阅。

是否要调用[对象描述]?Description是一个NSObject函数。这可能是问题所在,我有一个名为Description的实例变量,我完全忘记了NSObject的Description方法,我只是仔细检查了一下,然后用[pieceSession removeObjectAtIndex:section-2]删除了这个实例;是同一个例子,是得到等质量的方法。对不起,我不知何故误读了你的帖子。我以为你在用NSMutableSet。什么是NSMutableOrdered集?我在文档中找不到这一点。为什么在添加工件时会对已删除的Other实例调用isEqual?另外,NSSet是无序的,但isEqual用于确定添加的对象是否是重复的。抱歉,我误读了帖子,以为Kyle使用的是NSMutableSet。谢谢Kristian,这里有一些答案。我确信0x80d5680是之前删除的实例。我使用removeObjectAtIndex方法删除它。我可以在添加对象后修改它们的状态,但在这种特定情况下,我不这样做。我修改了我的原始帖子,以包含我的片段哈希方法。您的isEqual方法不会覆盖NSObject的isEqual,它只接受一个id类型的参数。您的实现实际上重载了该方法。不知道这是否是故意的,但结果是一个片段的实例永远不等于另一个片段的实例。另外,关于散列方法,您是否知道,如果字符串不是以数字开头(忽略前导空格),intValue将返回0?我假设NSMutableOrderedSet在内部使用NSMutableSet确定重复项,再加上NSMutableArray以保持顺序。如果将对象添加到这样的数据结构中,然后以哈希值更改的方式修改其状态,则删除时将发生以下情况:它将通过其索引在内部数组中找到该对象,但在集合中找不到该对象,因为哈希值已更改。由于有序集保留了该对象,并且在数组中找到了该对象,因此将释放该对象,但该对象仍保留在该集中,从而在插入下一个对象时导致异常。总之,请确保哈希值稳定。将散列值不稳定的对象放入散列数据结构是一个非常糟糕的主意。谢谢Kristian,你建议我用什么来使散列稳定?