9

是否有任何特殊原因导致尝试在NSMutableDictionaryusing an NSIndexPathas a中存储和检索值key可能会失败?

我最初尝试这样做是为了将高度 ( )存储NSMutableDictionary为. 每次您点击 a时,该单元格将根据存储在该特定值中的值在两个不同的高度之间扩展或收缩:UITableViewCellself.cellHeightsUITableViewUITableViewCellNSMutableDictionaryindexPath

- (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:via中获取单元格高度[self.cellHeights objectForKey:indexPath]就可以了。但是,尝试在tableView:heightForRowAtIndexPath:via中获取单元格高度[self.cellHeights objectForKey:indexPath]总是返回 nil,因为用于存储高度的 indexPath 似乎与用于获取单元格高度的 indexPath 不匹配,即使它们具有相同的值indexPath.sectionindexPath.row。因此,“相同”索引路径的新对象被添加到self.cellHeights(因为此后self.cellHeights.count增加明显)。

当您使用行()作为键将单元格高度存储在 NSMutableDictionary 中时,不会发生这种情况[NSNumber numberWithInteger:indexPath.row]......所以这就是我现在正在做的事情,但我想了解为什么indexPath不能作为键工作。

4

3 回答 3

13

尽管我在讨论中迟到了,但这里有一个快速简单的解决方案,它允许您使用 NSIndexPath 实例作为字典键。

只需通过添加以下行来重新创建indexPath:

indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];

瞧。tableView:heightForRowAtIndexPath:在内部使用NSMutableIndexPath实例(正如您在断点中看到的那样)。不知何故,这些实例NSIndexPath在计算哈希键时似乎不合作。

通过将其转换回NSIndexPath,然后一切正常。

于 2014-02-10T18:58:36.473 回答
5

@Jean 的回答似乎可以接受,但这个问题已经在这里得到了更详细的回答。简而言之,UITableView有时使用实例NSMutableIndexPath而不是NSIndexPath这两个类的实例永远不会相等,因为[NSMutableIndexPath class] != [NSIndexPath class]. 解决方法是始终NSIndexPath为依赖isEqualor的任何内容生成一个键hash,例如查找字典键:

- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath class] == [NSIndexPath class]) {
        return indexPath;
    }
    return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}
于 2014-02-10T19:28:17.217 回答
1

NSDictionary要使对象作为、和协议的键可靠地工作isEqual:,必须实现几件事。hashCopyable

我不太确定它NSIndexPath是否打算用作字典的键(因为它被用作数组的索引)。

我的猜测是hash对于类的不同实例没有正确实现。另请注意,有些表委托方法是用 调用的NSIndexPath,有些是用调用的NSMutableIndexPath。这可能会有所作为。

于 2013-11-01T15:38:26.550 回答