Reputation: 8412
I'm using a NSMutableDictionary
to store some values about some UITableViewCell
s, so I'm using instances of NSIndexPath
as keys. Everything works as expected on iOS 6, but when I run the exact same code in the iOS 5 Simulator, weird things happen. So I printed the contents of the dictionary to the console:
Printing description of heights:
{
"<UIMutableIndexPath 0x6a8a3d0> 2 indexes [1, 3]" = 100;
"<UIMutableIndexPath 0x6a8a3d0> 2 indexes [1, 3]" = 100;
"<UIMutableIndexPath 0x6a8a3d0> 2 indexes [1, 3]" = 100;
}
On iOS 6 it looks like this:
Printing description of heights:
{
"<UIMutableIndexPath 0x75ca8c0> 2 indexes [0, 1]" = 44;
"<UIMutableIndexPath 0x75caa70> 2 indexes [0, 0]" = 10;
"<UIMutableIndexPath 0x75ca500> 2 indexes [1, 0]" = 100;
"<UIMutableIndexPath 0x717df70> 2 indexes [1, 1]" = 67;
"<UIMutableIndexPath 0x715a3e0> 2 indexes [1, 2]" = 67;
"<UIMutableIndexPath 0x717def0> 2 indexes [1, 3]" = 67;
}
Which is how it should be, obviously! Why would the dictionary on iOS 5 store different values for exactly the same key?
Edit: Some code...
The dictionary creating is just
self.heights = [[NSMutableDictionary alloc] init];
I set values using the new subscripting syntax, i.e. like so:
self.heights[indexPath] = minHeight;
(indexPath
is a NSIndexPath
, minHeight
is a NSNumber
.)
I set these values dynamically as the delegate requests them:
- (NSNumber *)heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (![indexPath isInTableView:self.tableView])
{
@throw [NSException exceptionWithName:NSInvalidArgumentException reason:@"indexPath not in tableView" userInfo:nil];
}
NSNumber *storedHeight = self.heights[indexPath];
if (storedHeight != nil)
{
return storedHeight;
}
NSNumber *minHeight = self.minimumHeights[indexPath];
self.heights[indexPath] = minHeight;
return minHeight;
}
The minimumHeights
NSDictionary
also holds NSNumber
s for every indexPath in a table view.
Upvotes: 2
Views: 516
Reputation: 19641
I remember reading about NSIndexPath
methods isEqual:
or hash
or both changing in iOS6 or just that there was a bug in iOS 5. In any case, it seems you can't use them as dict keys.
Try using different keys. Maybe using its description
method or a custom string built with the section and row.
#define idx2key(_ip) [NSString stringWithFormat:@"%d:%d", [_ip section], [_ip row]]
...
self.heights[idx2key(indexPath)] = minHeight;
...
In old NSIndexPath
Apple said:
NSIndexPath objects are uniqued and shared. If an index path containing the specified index or indexes already exists, that object is returned instead of a new instance.
That paragraph doesn't exist anymore. I guess internal comparison of instances have been changed too.
Upvotes: 3