使用NSMutableDictionary
作为NSIndexPath
尝试在key
中存储和检索值可能会失败,是否有任何特殊原因?
我最初尝试执行此操作,以便为NSMutableDictionary
存储UITableViewCell
self.cellHeights
个高度(UITableView
)。每次点击UITableViewCell
时,该单元格将根据NSMutableDictionary
中indexPath
存储的值,在两个不同高度之间展开或收缩:
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSNumber *heightNSNumber = [self.cellHeights objectForKey:indexPath];
if (!heightNSNumber)
{
heightNSNumber = [NSNumber numberWithFloat:100.0];
[self.cellHeights setObject:heightNSNumber forKey:indexPath];
}
return [heightNSNumber floatValue];
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSNumber *heightNSNumber = [self.cellHeights objectForKey:indexPath];
if (!heightNSNumber)
{
heightNSNumber = [NSNumber numberWithFloat:100.0];
[self.cellHeights setObject:heightNSNumber forKey:indexPath];
}
if ([heightNSNumber floatValue] == 100.0)
{
[self.cellHeights setObject:[NSNumber numberWithFloat:50.0]
forKey:indexPath];
} else {
[self.cellHeights setObject:[NSNumber numberWithFloat:100.0]
forKey:indexPath];
}
[tableView beginUpdates];
[tableView endUpdates];
}
由于我不知道的原因,通过tableView:didSelectRowAtIndexPath:
将单元格高度设置为[self.cellHeights objectForKey:indexPath]
可以正常工作。但是,尝试通过tableView:heightForRowAtIndexPath:
获取[self.cellHeights objectForKey:indexPath]
内的单元格高度始终返回nil,因为用于存储高度的indexPath似乎与用于获取单元格高度的indexPath不匹配,即使它们对indexPath.section
和indexPath.row
具有相同的值。因此,self.cellHeights
添加了一个“相同”索引路径的新对象(此后self.cellHeights.count
增加,因此显而易见)。
当您使用行([NSNumber numberWithInteger:indexPath.row]
)作为键将单元格高度存储在NSMutableDictionary中时,不会发生这种情况......这就是我现在正在做的事情,但是我想了解为什么indexPath
没有成为关键。
答案 0 :(得分:13)
虽然我讨论的时间较晚,但这是一个快速而简单的解决方案,允许您将NSIndexPath实例用作字典键。
只需重新创建 indexPath,方法是添加以下行:
indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
瞧。 tableView:heightForRowAtIndexPath:
在内部使用NSMutableIndexPath
个实例(正如您在断点处看到的那样)。不知何故,这些实例在计算哈希键时似乎与NSIndexPath
不合作。
通过将其转换回NSIndexPath
,一切正常。
答案 1 :(得分:4)
@ Jean的答案似乎可以接受,但这个问题一直是answered in more detail here。简而言之,UITableView
有时会使用NSMutableIndexPath
而不是NSIndexPath
的实例,而这两个类的实例永远不会相等,因为[NSMutableIndexPath class] != [NSIndexPath class]
。解决方法是始终为依赖NSIndexPath
或isEqual
的任何内容生成密钥hash
,例如查找字典密钥:
- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
if ([indexPath class] == [NSIndexPath class]) {
return indexPath;
}
return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}
答案 2 :(得分:1)
对象必须实现几件事才能可靠地作为NSDictionary
的关键,即isEqual:
,hash
和Copyable
协议。
我不太确定NSIndexPath
是否有意成为词典的关键(因为它被作为数组的索引)。
我的猜测是hash
未针对该类的不同实例正确实现。另请注意,某些表委托方法使用NSIndexPath
调用,而某些调用NSMutableIndexPath
调用。这可能会带来不同。