2011-03-28 11 views
15

जब भी मेरे पास UITableView में डेटा होता है और मैं हटाना शुरू करता हूं, तो यह ठीक काम करता है। हालांकि, जब मैं तालिका में अंतिम वस्तु पर जाता हूं, और इसे हटा देता हूं, तो यह क्रैश हो जाता है।NSInternalInconsistencyException (पंक्तियों की अमान्य संख्या)

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the row from the data source 
     if ([myData count] >= 1) { 
      [tableView beginUpdates]; 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [myData removeObjectAtIndex:[indexPath row]]; 

      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
      NSString *documentsDirectory = [paths objectAtIndex:0]; 
      NSString *somepath = [documentsDirectory stringByAppendingPathComponent:@"something.plist"]; 
      [myData writeToFile:somepath atomically:YES]; 
      [table reloadData]; 
      if ([myData count] == 0) { 
       [tableView endUpdates]; 
       [tableView reloadData]; 
      } 
      else { 
      [tableView endUpdates]; 
      } 
     } 
    } 
} 

और यह भी इस:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    // Return the number of rows in the section. 
    if ([myData count] != 0) { 
     return [myData count]; 
    } 
    else { 
     return 1; 
    } 
} 

कारण मैं 1 लौटने कर रहा हूँ है, क्योंकि मैं बना रहा हूं

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted).'

यहाँ कैसे मैं संपादन कर रहा हूँ सामान है एक सेल जो cellForRowAtIndexPath में "कोई डेटा सहेजा नहीं गया" कहता है। यहां मेरा मतलब है:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; 
    }  
    if ([cityData count] != 0) { 
     //normal setup removed for clarity 
    } 
    else { 
     cell.textLabel.text = @"No saved data!"; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14]; 
    cell.textLabel.textAlignment = UITextAlignmentCenter; 
    cell.selectionStyle = UITableViewCellSelectionStyleNone; 
     cell.tag = 1; 
    return cell; 
    } 
} 

तो, मैं इस त्रुटि को प्राप्त करने के लिए अपने संपादन कोड में क्या गलत कर रहा हूं? धन्यवाद!

उत्तर

28

यदि आप अपनी तालिका में अंतिम पंक्ति को हटाते हैं, तो UITableView कोड अपेक्षा करता है कि 0 पंक्तियां शेष हों। यह निर्धारित करने के लिए कि आपके कितने शेष हैं, यह UITableViewDataSource विधियों को कॉल करता है। चूंकि आपके पास "कोई डेटा" सेल नहीं है, इसलिए यह 1, 0 नहीं देता है। इसलिए जब आप अपनी तालिका में अंतिम पंक्ति हटाते हैं, तो अपनी "कोई डेटा" पंक्ति डालने के लिए -insertRowsAtIndexPaths:withRowAnimation: पर कॉल करने का प्रयास करें। साथ ही, आपको इस विधि में कहीं भी -reloadData पर कॉल नहीं करना चाहिए। -endUpdates प्रभावित पंक्तियों को पुनः लोड करने का ख्याल रखेगा। इसे आज़माएं:

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the row from the data source 
     if ([myData count] >= 1) { 
      [tableView beginUpdates]; 
      [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      [myData removeObjectAtIndex:[indexPath row]]; 

      NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
      NSString *documentsDirectory = [paths objectAtIndex:0]; 
      NSString *somepath = [documentsDirectory stringByAppendingPathComponent:@"something.plist"]; 
      [myData writeToFile:somepath atomically:YES]; 

      if ([myData count] == 0) { 
       [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
      } 
      [tableView endUpdates]; 
     } 
    } 
} 
+1

बिल्कुल सही, धन्यवाद! –

+3

आप क्या कर सकते हैं केवल कॉल टेबल देखें हटाएं RowAtIndexPaths यदि [डेटा गिनती]> 0 और बाद में कॉल पुनः लोड करेंडेटा। इस तरह आप अंतिम सेल को "डेटा" सेल के लिए उपयोग करने जा रहे हैं और पुनः लोड करने से यह सुनिश्चित होता है कि प्रतिनिधि तालिकादृश्य में सही जानकारी लोड करता है। – EeKay

+0

धन्यवाद, इससे मुझे भी मदद मिली! –

1

पहले myData से हटाएं और फिर तालिकादृश्य से हटा दें।

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    // Return the number of rows in the section. 
    return [myData count]; 
} 

नष्ट कर दिया अंतिम पंक्ति होने के बाद, आप पूरे हिस्से को हटाना हो सकता है:

-(void)tableView:(UITableView *)tableView commitEditingStyle: 
(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 

if (editingStyle == UITableViewCellEditingStyleDelete) { 
     //somehting... 
     [myData removeObjectAtIndex:[indexPath row]]; 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     //somehting... 
    } 
} 

}

1

विधि tableView:numberOfRowsInSection हमेशा पंक्तियों की सही संख्या लौटना चाहिए। को beginUpdates और endUpdated ब्लॉक के भीतर बस कॉल करें;

-(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 
    if (editingStyle == UITableViewCellEditingStyleDelete) { 
     // Delete the row from the data source 
     [tableView beginUpdates]; 
     [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 
     [myData removeObjectAtIndex:[indexPath row]]; 
     NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
     NSString *documentsDirectory = [paths objectAtIndex:0]; 
     NSString *somepath = [documentsDirectory stringByAppendingPathComponent:@"something.plist"]; 
     [myData writeToFile:somepath atomically:YES]; 
     if ([myData count] == 0) { 
      // NEW! DELETE SECTION IF NO MORE ROWS! 
      [tableView deleteSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade]; 
     } 
     [tableView endUpdates]; 
    } 
} 
संबंधित मुद्दे