Issues using NSIndexPath as key in NSMutableDictionary?

99封情书 提交于 2019-12-04 03:34:35
Jean Le Moignan

Although I'm late in the discussion, here's a quick and simple solution that will allow you to use NSIndexPath instances as dictionary keys.

Just recreate the indexPath by adding the following line:

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

Voilà. tableView:heightForRowAtIndexPath: uses NSMutableIndexPath instances internally (as you would see with a breakpoint). Somehow those instances seem uncooperative with NSIndexPath when calculating hash keys.

By converting it back to an NSIndexPath, then everything works.

Timothy Moose

@Jean's answer seems acceptable, but this question has been answered in more detail here. In short, UITableView sometimes uses instances of NSMutableIndexPath instead of NSIndexPath and instances of these two classes are never equal because [NSMutableIndexPath class] != [NSIndexPath class]. The workaround is to always generate a key NSIndexPath for anything that relies on isEqual or hash, such as looking up dictionary keys:

- (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
{
    if ([indexPath class] == [NSIndexPath class]) {
        return indexPath;
    }
    return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
}

There are several things that must be implemented for an object to work reliably as a key for NSDictionary, namely isEqual:, hash and Copyable protocol.

I am not very sure that NSIndexPath was ever intented to work as a key for dictionaries (because it was made to be an index for arrays).

My guess is that hash is not implemented correctly for different instances of the class. Also note that some of the table delegate methods are called with NSIndexPath and some with NSMutableIndexPath. That's probably making the difference.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!