9

NSMutableDictionaryNSIndexPathkey kullanarak bir değeri depolamayı ve geri almayı denemenin neden başarısız olabilir? NSMutableDictionary'da NSIndexPath anahtarını kullanan sorunlar?

Başlangıçta bir UITableView için bir NSMutableDictionary UITableViewCell yükseklikleri ( self.cellHeights) depolamak için bunu denedi. Bana bilinmeyen nedenlerden dolayı

- (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: içinde hücre yüksekliği alma: Her zaman hücre genişletmek ya o belirli indexPath için NSMutableDictionary saklanan değere bağlı olarak iki farklı yüksekliğe arasındaki sözleşme olur ya o, bir UITableViewCell aday [self.cellHeights objectForKey:indexPath] aracılığıyla sadece iyi çalışıyor. Ancak, tableView:heightForRowAtIndexPath: içinde tableView:heightForRowAtIndexPath: içinde hücre yüksekliğini almayı denemek her zaman nil değerini döndürür çünkü indexPath'in yüksekliği depolamak için kullandığı dizin, indexPath.section için aynı değerlere sahip olsa bile hücre yüksekliğini almak için kullanılan indexPath ile eşleşmiyor ve indexPath.row. Bu nedenle, "aynı" dizin yolu için yeni bir nesne, self.cellHeights'a eklenir (daha sonra self.cellHeights.count arttıkça belirgin hale gelir).

Bu does değil o şimdilik yapıyorum yani ... anahtar olarak satır ([NSNumber numberWithInteger:indexPath.row]) kullanılarak NSMutableDictionary hücre yükseklikleri depolamak, ama nedenini indexPath anlamak istiyorum zaman ne Anahtar olarak çalışmıyor.

cevap

1

bir nesne NSDictionary için bir anahtar, yani isEqual:, hash ve Copyable protokolü olarak güvenilir çalışması için uygulanması gereken birkaç şey vardır.

NSIndexPath'un sözlükler için bir anahtar olarak çalışmak üzere tasarlandığından pek emin değilim (çünkü diziler için bir dizin oluşturulduğundan).

Tahminimce, sınıfın farklı örnekleri için hash doğru uygulanmadı. Ayrıca bazı tablo delege yöntemlerinin NSIndexPath ve bazılarının NSMutableIndexPath ile çağrıldığını unutmayın. Muhtemelen farkı yaratıyordur.

12

Tartışmaya geç olmamasına rağmen, burada NSIndexPath örneklerini sözlük tuşları olarak kullanmanıza olanak tanıyan hızlı ve basit bir çözüm var.

Sadece aşağıdaki satırı ekleyerek indexPath yeniden:

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

Voilà. tableView:heightForRowAtIndexPath:, dahili olarak (bir kesme noktasında göreceğiniz gibi) NSMutableIndexPath örneklerini kullanır. Bazı durumlarda, karma anahtarları hesaplarken bu örneklerin NSIndexPath ile işbirliği yapmadığı görülmektedir.

Bir geri NSIndexPath dönüştürerek, her şey çalışıyor.

+0

Holy Moly: geçici çözüm her zaman böyle sözlük anahtarlarını ararken olarak, isEqual veya hash dayanan herhangi bir şey için bir anahtar NSIndexPath üretmektir. Bu DRIVING ME MAD oldu. Saatlerce, sözlükimin neden bir KDEW varlığımın bir indexPath için geri geldiğini anlamaya çalışırken interneti taradım. Kesinlikle çıldırtıcı. Göndermek için teşekkürler. – Andy

3

@ Jean'in cevabı kabul edilebilir görünüyor, ancak bu soru answered in more detail here oldu. Kısacası, UITableView bazen NSIndexPath yerine NSMutableIndexPath örneklerini kullanır ve bu iki sınıfın örnekleri hiçbir zaman eşit değildir, çünkü [NSMutableIndexPath class] != [NSIndexPath class].

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