菜鸟教程小白 发表于 2022-12-11 19:19:10

ios核心数据: make sure object is deleted from data source


                                            <p><p>更新:在评论中有人指出我不必要地分派(dispatch)到主线程。在删除调度和不必要的 <code>begin/end updates</code> 之后,现在当我尝试删除一个单元格时,它会调用 <code>didChangeObject</code> 与 case <code>NSFetchedResultsChangeUpdate</code> (相反到 <code>NSFetchedResultsChangeDelete</code>),它调用 <code>configureCell</code>。</p>

<p>使程序崩溃的行是 <code>CollectedLeaf* theCollectedLeaf = ;</code> 在下面的方法中。崩溃日志是,<code>节列表中索引 20 处没有节</code>。</p>

<pre><code>- (void)configureCell:(SpeciesCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    CollectedLeaf* theCollectedLeaf = ;
    ;
}
</code></pre>

<hr/>

<p>每次滑动以从表格中删除单元格时,我都会收到 <code>Invalid update: invalid number of rows in section</code> 错误。我在 <code>controllerDidChangeContent</code> 的 <code></code> 处获得断点。 </p>

<p>在许多 SO 帖子中,出现此错误的原因是在从表中删除行之前尚未从数据源中删除对象。我从 <code>commitEditingStyle</code> 中的数据源中删除对象,该对象在 <code>didChangeObject</code> 中的 <code>deleteRowsAtIndexPaths</code> 之前调用。</p>

<p>尽管我下了订单,但我仍然收到 <code>Invalid update</code> 的事实让我认为我没有正确/成功地从数据源中删除它。我还是 iOS 新手 - 如何确保从我的核心数据中删除对象?</p>

<pre><code>- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    ;
}

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath {
    switch(type) {

      case NSFetchedResultsChangeInsert:
            ;

            
                        withRowAnimation:UITableViewRowAnimationFade];
            ;
            break;

      case NSFetchedResultsChangeDelete:
            NSLog(@&#34;delete called&#34;);
            
                        withRowAnimation:UITableViewRowAnimationFade];


            break;

      case NSFetchedResultsChangeUpdate:
         //
                   // atIndexPath:indexPath];
             withRowAnimation:UITableViewRowAnimationAutomatic];
            NSLog(@&#34;fetched update&#34;);
            break;

      case NSFetchedResultsChangeMove:
            
                        withRowAnimation:UITableViewRowAnimationFade];
            
                        withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id &lt;NSFetchedResultsSectionInfo&gt;)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    switch(type)
    {
      case NSFetchedResultsChangeInsert:
             withRowAnimation:UITableViewRowAnimationFade];
            break;

      case NSFetchedResultsChangeDelete:
             withRowAnimation:UITableViewRowAnimationFade];
            break;
      case NSFetchedResultsChangeMove:
            break;
      case NSFetchedResultsChangeUpdate:
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    ;
}
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(_segmentedControl.selectedSegmentIndex == 1) {
      NSLog(@&#34;index path at editingStyleForRowAtIndexPath %@&#34;, indexPath);
      return UITableViewCellEditingStyleDelete;
    }
    return NULL;
}

- (void)tableView:(UITableView*)tableView didEndEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
    // ;
    if(_segmentedControl.selectedSegmentIndex == 1) {
      for (UITableViewCell *cell in ) {
            for (UIView *subview in cell.contentView.subviews)
                ;
      }
    }
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    /*Only allow deletion for collection table */
    if(_segmentedControl.selectedSegmentIndex == 1) {
      if (editingStyle == UITableViewCellEditingStyleDelete)
      {
            NSLog(@&#34;index path at commitediting style %@&#34;, indexPath);
            CollectedLeaf* collectedLeaf = ;
            LeafletPhotoUploader * leafletPhotoUploader = [ init];
            leafletPhotoUploader.collectedLeaf = collectedLeaf;

            if() {
                ;
            }

            // Delete the managed object for the given index path
            NSManagedObjectContext *context = ;
                ];

            // Save the context.
            NSError *error;
            if (!)
            {
                NSLog(@&#34;Failed to save to data store: %@&#34;, );
                NSArray* detailedErrors = [ objectForKey:NSDetailedErrorsKey];
                if(detailedErrors != nil &amp;&amp; &gt; 0)
                {
                  for(NSError* detailedError in detailedErrors)
                  {
                        NSLog(@&#34;DetailedError: %@&#34;, );
                  }
                }
                else
                {
                  NSLog(@&#34;%@&#34;, );
                }
            }
      }
    }
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @&#34;speciesCell&#34;;

    SpeciesCell* speciesCell = (SpeciesCell*);

    ;
    speciesCell.labelCheckMark.backgroundColor = ;

    return speciesCell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {

    return 1;
}
- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    id &lt;NSFetchedResultsSectionInfo&gt; sectionInfo = [ objectAtIndex:section];
    if( == 0){
      UILabel *noDataLabel         = [ initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, tableView.bounds.size.height)];
      noDataLabel.text             = @&#34;Press the Snap It! tab to start collecting!&#34;;
      //Start your collection by tapping on the Snap It! tab.&#34;;
      noDataLabel.textColor      = ;
      noDataLabel.textAlignment    = NSTextAlignmentCenter;
      tableView.backgroundView = noDataLabel;
      tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    }
    return ;
}
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p> <a href="https://stackoverflow.com/questions/25049923/terminating-app-due-to-uncaught-exception-nsinternalinconsistencyexception-re" rel="noreferrer noopener nofollow">This post saved me</a> </p>

<p><code>objectAtIndexPath</code> 有很多错误,只能在边界检查中调用,所以我现在使用嵌套 if 语句中的核心数据对象完成所有工作</p>

<pre><code>    CollectedLeaf* theCollectedLeaf = nil;
    if ([ count] &gt; ){
      id &lt;NSFetchedResultsSectionInfo&gt; sectionInfo = [ objectAtIndex:];
      if ( &gt; ){
            theCollectedLeaf = ;

      //do whatever else I need, delete the object, etc
      }

    }
</code></pre>

<p>正如链接帖子所述,</p>

<blockquote>
<p>&#34;The reason you are getting an exception is that the state of the
NSFetchedResultsController is getting out of sync with the state of
the tableview. When your crash happens the tableView just asked your
delegate methods (numberOfSectionsInTableView and
tableView:numberOfRowsInSection: for the number of rows and sections.
When it asked that, the NSFetchedResultsController had data in it, and
gave positive values (1 section, 3 rows). But in-between that
happening and your crash, the entities represented by the
NSFetchedResultsController were deleted from the
NSManagedObjectContext. Now cellForRowAtIndexPath: is being called
with an outdated indexPath parameter.&#34;</p>
</blockquote></p>
                                   
                                                <p style="font-size: 20px;">关于ios核心数据: make sure object is deleted from data source,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/47340419/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/47340419/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios核心数据: make sure object is deleted from data source