UITableView löschen/hinzufügen Zeile-Ursachen, CoreData: Ernst-Anwendung Fehler, wenn ein anderes Objekt ausgewählt wurde in der MasterView von einem SplitViewController

Update 18/3 #2. Ich habe angefangen zu zählen beginUpdates und EndUpdates um sicherzustellen, dass Sie sind auch. Direkt vor es ist eine Ausnahme, Sie aus dem Takt geraten. Nicht sicher, warum aber.

UPDATE 18/3: ich glaube, ich habe das problem gefunden, aber ich bin mir nicht sicher, ob ich weiß, wie es zu lösen ist. Nach einigen versuchen für ein paar Stunden, ich fand, ich könnte nur zum Absturz der app, wenn ich ausgewählt hatte mehr als ein Element in der master-tableview der svc während dieser Sitzung.
Wenn ein anderes Element ausgewählt ist, in der master-tableview, die detail-Tabelle anzeigen, wird ein neues Objekt gesetzt und refreshtables aufgerufen wird, AUCH WENN es auf halbem Weg durch ein update/verschieben/löschen/einfügen " - Zyklus. Daher das problem; ich denke, es hat Anweisungen, um ein update der alten story-Objekt, obwohl ein neues story-Objekt festgelegt wurde, auf der detailviewcontroller.

Wie bekomme ich die animation/coredata/tableview aktualisiert werden vollständig verarbeitet, bevor eine neue Geschichte ist in der detail-Ansicht? Ich speichern Sie die änderungen an den managedObjectContext, wenn setEditting == NEIN. Ich vermute, ich brauche, um eine benutzerdefinierte setStory setter, dass die Prozesse alle updates, um die UITableView/CoreData, die vor der Annahme der neuen Objekt?

Dieser code aufgerufen wird, wird auf dem master-tableview-controller der svc in didSelectRowAtIndexPath:

[detailViewController setStory:storySet]; //where storySet is the new story object
[detailViewController refreshTables];

Ich habe intermittierende Fehler auf dem Versuch zum löschen der Zeile, wo die Handlung nicht animiert und die Anwendung hängt im wesentlichen mit der folgenden Fehlermeldung (die Zeile wird gelöscht, von der CoreData-set obwohl). Dies passiert, wenn ich die gewählt haben, mehr als eine Zeile aus der master-tableview-controller in der svc in einer Sitzung.

Nach etwas googlen dachte ich, es könnte ein problem mit (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id), die aufgerufen wird, nachdem ein update zum animieren von änderungen, die der Benutzer gemacht hat.

Wie kann ich das beheben diese intermittierenden Fehler?

  • 16/3I habe versucht, wirklich vereinfacht meinen code. Ich habe entfernt alle Anrufe zu den Managed Object Context, und legen Sie Sie in setEditing, entfernt überflüssige [self.tableview reloadData] und [self.tableview setneedsdisplay] und entwertet die 'Neuordnung' bool vollkommen (es ist immer noch im code, aber es ist immer auf NO gesetzt, so macht es keinen Unterschied). Der UITableView ist stabiler denn je, aber ich habe noch zu verwalten, um intermittierende Fehler auf löschen (und gelegentlich auf hinzufügen (add) - es scheint eine Weile dauern, bis Absturz, aber es wird noch.**
  • 15/3: ich denke, es hat etwas zu tun mit dem CoreData /UITableView wird out-of-sync - CoreData denkt, es hat weniger oder mehr als die UITableView
  • Es ist kein problem mit CoreData-set, es ist nur die animation/UI-Seite der Dinge (entfernt)
  • Es zeitweise, nur bei manchen löscht
  • Nach etwas Hilfe von railwayparade ich umgesetzt NSFetchedResultsChangeMove in didChangeObject: die Feste der bewegten Fehler, aber nicht die Fehler löschen.

Kann jemand sehen, was ich verpasst habe oder dass ich überprüfen kann? Gerne geben Sie weitere Informationen, wenn das hilft das problem zu lösen.

Entschuldigung für die obszöne Menge an code hier gepostet.

Den Fehler:

CoreData: Fehler: Schwerwiegender Anwendungsfehler. Eine Ausnahme gefangen wurde
vom Delegierten des NSFetchedResultsController während eines Anrufs zu
-controllerDidChangeContent:. versuchen, fügen Sie die Zeile 3 in Abschnitt 0, aber es sind nur 3 Zeilen in Abschnitt 0 nach dem update mit der userInfo
(null)

//
// MakeSentenceTableViewController.h
// StoryBot
//
// Created by Glen Storey on 25/10/10.
// Copyright 2010 Glen Storey. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AddStoryItem.h"
#import "Story.h"
#import "Sentence.h"


@interface MakeSentenceTableViewController : UITableViewController <NSFetchedResultsControllerDelegate, AddStoryItemDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate, UITextFieldDelegate, UIPopoverControllerDelegate> {
    NSManagedObjectContext      *managedObjectContext;  
    NSFetchedResultsController  *fetchedResultsController;
    UIPopoverController         *popoverController;
    UIBarButtonItem             *playButtonItem;
    UIBarButtonItem             *addButtonItem;

    BOOL                        reordering;
    BOOL                        insert;
    BOOL                        delete;
    BOOL                        move;

    int                         beginUpdatesCount;
    int                         endUpdatesCount;

}
@property (nonatomic, retain)   Story *story;
@property (nonatomic, retain)   NSManagedObjectContext *managedObjectContext;
@property (nonatomic, retain)   UIBarButtonItem *playButtonItem;
@property (nonatomic, retain)   UIBarButtonItem *addButtonItem;
@property BOOL reordering,  insert,  delete,  move;

-(IBAction)createStoryModal:(id)sender;
-(void)refreshTables;
-(IBAction)pushShare:(id)sender;


@end


//
// MakeSentenceTableViewController.m
// 
//
// Created by Glen Storey on 25/10/10.
// Copyright 2010 Glen Storey. All rights reserved.
//

#import "MakeSentenceTableViewController.h"
#import "ShareViewController.h"
#import "StoryBotAppDelegate.h"

@implementation MakeSentenceTableViewController
@synthesize story, managedObjectContext, addButtonItem, playButtonItem, reordering, insert, delete, move;

-(void)addStoryItemAction:(NSString*)text order:(NSNumber*)order image:(NSString*)image thumb:(NSString*)thumb{

    NSLog(@"Text: %@, Order: %@, Image: %@.", text, order, image);
    NSLog(@"beginUpdatesCount: %d vs. endUpdatescount: %d", beginUpdatesCount, endUpdatesCount);

    NSSet *sentences = [story sentences];
    NSNumber *maxOrder = [sentences valueForKeyPath:@"@max.order"];
    NSLog(@"maxOrder: %@", maxOrder);

    if(maxOrder == 0){

        maxOrder = [[NSNumber alloc] initWithInteger: 0];
    }

    //make a new sentence!
    Sentence *sentence = [NSEntityDescription insertNewObjectForEntityForName:@"Sentence" 
                                                       inManagedObjectContext:managedObjectContext];

    [sentence setText: text];
    [sentence setImage: image];
    [sentence setThumb: thumb];
    [sentence setBelongsTo: story];
    if([maxOrder intValue] >= 1 ){
            [sentence setOrder: [[NSNumber alloc] initWithInteger:[maxOrder intValue]+1]]; 
    }else{
            [sentence setOrder: [[NSNumber alloc] initWithInteger:1]];
    }
    NSMutableSet *mutableSet = [[NSMutableSet alloc] initWithSet:sentences];
    [mutableSet addObject:sentence];

    //NSLog(@"sentences before setWithSet %@", mutableSet);

    sentences = [[NSSet alloc] initWithSet: mutableSet];

    //NSLog(@"sentences after setWithSet %@", sentences); 

    [story setSentences:sentences];

    //NSError *error;  

    //BOOL isSaved = [managedObjectContext save:&error];
    //NSLog(@"isSaved? %@", (isSaved ? @"YES" :@"NO ") );

    //if (!isSaved) {
        //NSLog(@"%@:%s Error saving context: %@", [self class], _cmd, [error localizedDescription]);
        //Don't worry about this warning - just rem it out when finished (just a log)
      // return;
    //} 

    [sentences release];
    [mutableSet release];

    //[self.tableView reloadData];
    //[self.tableView setNeedsDisplay];
    [self dismissModalViewControllerAnimated:YES];  



}

#pragma mark -
#pragma mark View lifecycle

-(id)initWithNibName:(NSString*)name bundle:(NSBundle*)bundle;
{
    self = [super initWithNibName:name bundle:bundle];

    if (self) {

        self.title = @"My Stories";

        addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd 
                                                                                       target:self
                                                                                       action:@selector(createStoryModal:)];

        playButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemPlay 
                                                                                        target:self
                                                                                        action:@selector(pushShare:)];
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
            [addButtonItem setEnabled:NO];
            [playButtonItem setEnabled:NO];
        }


        NSArray* toolbarItems = [NSArray arrayWithObjects:
                                 addButtonItem,
                                 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace 
                                                                               target:nil
                                                                               action:nil],
                                 playButtonItem,
                                 nil];

        [toolbarItems makeObjectsPerformSelector:@selector(release)];
        self.toolbarItems = toolbarItems;  

        //NSLog(@"self: %@ self.toolbarItems: %@", self, self.toolbarItems);


        //Do I need to release UIBarButtonItems? 

        NSLog(@"initWithNibName:");
    }



    return self;
}

-(void)refreshTables{

    //use this to refresh for new table content. Also calls self.tableview reloadData so you don't need to call it afterward. 

    NSLog(@"===================================refreshTables");
    NSLog(@"story object %@", story);

    if (managedObjectContext == nil) 
    { 
        NSLog(@"managedObjectContext == nil");
        managedObjectContext = [(StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
        NSLog(@"After managedObjectContext: %@",  managedObjectContext);
    }else{
        NSLog(@"managedObjectContext != nil");
    }



    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentence" inManagedObjectContext:managedObjectContext];
    [request setEntity:entity];

    //sorting stuff:
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending: YES];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
    [request setSortDescriptors:sortDescriptors];
    [sortDescriptors release];
    [sortDescriptor release];

    NSPredicate *predicateTitle = [NSPredicate predicateWithFormat:@"belongsTo=%@",story];
    [request setPredicate :predicateTitle];

    NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
    [dateFormatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss"];
    NSString *dateString = [dateFormatter stringFromDate:[story creationDate]];

    NSLog(@"dateString: %@", dateString);

    fetchedResultsController = [[NSFetchedResultsController alloc] 
                                initWithFetchRequest:request managedObjectContext:managedObjectContext 
                                sectionNameKeyPath:nil cacheName:dateString];

    fetchedResultsController.delegate = self;

    [request release];

    NSError *error;
    [fetchedResultsController performFetch:&error];

    [self.tableView reloadData];

}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.title = @"My Story";

    NSLog(@"Passed Story Object: %@", story);
    //NSLog(@"managedObjectContext: %@", managedObjectContext); 
    //Need a predicate for belongsTo here.

    self.tableView.rowHeight = 50;

    if(story != NULL){
        if (managedObjectContext == nil) 
        { 
            NSLog(@"managedObjectContext == nil");
            managedObjectContext = [(StoryBotAppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
            NSLog(@"After managedObjectContext: %@",  managedObjectContext);
        }else{
            NSLog(@"managedObjectContext != nil");
        }



        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Sentence" inManagedObjectContext:managedObjectContext];
        [request setEntity:entity];

        //sorting stuff:
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"order" ascending: YES];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: sortDescriptor, nil];
        [request setSortDescriptors:sortDescriptors];
        [sortDescriptors release];
        [sortDescriptor release];

        NSPredicate *predicateTitle = [NSPredicate predicateWithFormat:@"belongsTo=%@",story];
        [request setPredicate :predicateTitle];



        fetchedResultsController = [[NSFetchedResultsController alloc] 
                                    initWithFetchRequest:request managedObjectContext:managedObjectContext 
                                    sectionNameKeyPath:nil cacheName:nil];

        fetchedResultsController.delegate = self;

        [request release];

        NSError *error;
        [fetchedResultsController performFetch:&error];




    }



#pragma mark -
#pragma mark Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    //Return the number of sections.
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    //Return the number of rows in the section.
    NSArray *sections = [fetchedResultsController sections];
    NSInteger count = 0;

    if ([sections count]){
        id <NSFetchedResultsSectionInfo> sectionInfo = [sections objectAtIndex:section];
        count = [sectionInfo numberOfObjects];

    }
    NSLog(@"# of rows in section %d", count);
    return count;

}


//Customize the appearance of table view cells.
- (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];
    }

    //Configure the cell...

    Sentence *sentenceAtCell = [fetchedResultsController objectAtIndexPath:indexPath];
    //NSLog(@"sentenceAtCell: %@", sentenceAtCell);

    cell.textLabel.text = [sentenceAtCell text];



    NSArray *paths       = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *uniquePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:[sentenceAtCell thumb]];


    //This should crop it as you want - you've just got to create cropRect.

    UIImage *largeImage = [UIImage imageWithContentsOfFile: uniquePath];
    CGRect cropRect = CGRectMake(0, 0, 66, 50); 


    /*if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        if ([[UIScreen mainScreen] scale] == 2) {
            //running an iPhone 4 or equiv. res device.
            cropRect = CGRectMake(15, 14, 100, 75); 
        }
    }*/


    CGImageRef imageRef = CGImageCreateWithImageInRect([largeImage CGImage], cropRect);
    cell.imageView.image = [UIImage imageWithCGImage: imageRef];
    CGImageRelease(imageRef);



    //NSLog(@"indexPath: %@", indexPath);

    return cell;
}

//Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {

        NSLog(@"Delete row");
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
        NSString *documentsDirectoryPath = [paths objectAtIndex:0];


        // 1. Look at the sentence we're about to delete.
        Sentence *sentenceRetire =      [fetchedResultsController objectAtIndexPath:indexPath];
        // 2. Does it have an order of 0? 
        NSLog(@"=================== sentenceRetire: %@", sentenceRetire);


        if([[sentenceRetire order] intValue] == 0){
                //     YES: Is there another sentence in this story?
                Story *storyRetire                      = [sentenceRetire belongsTo];
                NSSet *sentencesInRetiredSentenceSet    = [storyRetire sentences];


                if ([sentencesInRetiredSentenceSet count] > 1){
                    //         YES:    Set the sentence with the smallest order to an order of 0   
                    //                 then delete the sentence + files

                    NSPredicate *predicateTitle             = [NSPredicate predicateWithFormat:@"order>0"];
                    NSSet *sentencesWithPotentialToBeTitle  = [sentencesInRetiredSentenceSet filteredSetUsingPredicate:predicateTitle];
                    NSNumber *minOrder                      = [sentencesWithPotentialToBeTitle valueForKeyPath:@"@min.order"];  

                    NSPredicate *predicateOrder             = [NSPredicate predicateWithFormat:@"order=%d",[minOrder intValue]];
                    NSSet *sentenceWithPotentialToBeTitle   = [sentencesWithPotentialToBeTitle filteredSetUsingPredicate:predicateOrder];   

                    //note the sentence (singular) not sentences. This is the sentence who's order needs to be updated.     
                    NSLog(@"setenceWithPotentialToBeTitle (check order isn't null on crash): %@", sentenceWithPotentialToBeTitle);  
                    Sentence *sentenceToPromote = [sentenceWithPotentialToBeTitle anyObject];

                    //now we know which sentence to promote we can delete the sentence & Files.     
                    [managedObjectContext deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

                    NSString *imageTrash = [documentsDirectoryPath stringByAppendingPathComponent:(NSString*)[sentenceRetire image]];
                    NSString *thumbTrash = [documentsDirectoryPath stringByAppendingPathComponent:[sentenceRetire thumb]];

                    NSLog(@"About to delete these files: %@, %@", imageTrash, thumbTrash);

                    [fileManager removeItemAtPath:imageTrash error:NULL];
                    [fileManager removeItemAtPath:thumbTrash error:NULL];

                    //and promote the new title.    
                    [sentenceToPromote setOrder:[[NSNumber alloc] initWithInteger:0]];



                }else{
                    //         NO:     We're deleting this story
                    //                 Delete the files! 
                    [managedObjectContext deleteObject:storyRetire]; 
                    NSString *imageTrash = [documentsDirectoryPath stringByAppendingPathComponent:(NSString*)[sentenceRetire image]];
                    NSString *thumbTrash = [documentsDirectoryPath stringByAppendingPathComponent:[sentenceRetire thumb]];

                    //NSLog(@"About to delete these files: %@, %@", imageTrash, thumbTrash);

                    [fileManager removeItemAtPath:imageTrash error:NULL];
                    [fileManager removeItemAtPath:thumbTrash error:NULL];

                //Pop back. 
                    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {      
                        NSLog(@"last sentence in story - delete that story and point, somewhere!");
                        //probably delete the sentece to clear the table, then delete the story using storyRetire

                    } else{
                        [self.navigationController popViewControllerAnimated:YES];
                    }
            }

        }else{
        // NO: Delete the Sentence Object. 
            [managedObjectContext deleteObject:[fetchedResultsController objectAtIndexPath:indexPath]];

            NSString *imageTrash = [documentsDirectoryPath stringByAppendingPathComponent:(NSString*)[sentenceRetire image]];
            NSString *thumbTrash = [documentsDirectoryPath stringByAppendingPathComponent:[sentenceRetire thumb]];

            //NSLog(@"About to delete these files: %@, %@", imageTrash, thumbTrash);

            [fileManager removeItemAtPath:imageTrash error:NULL];
            [fileManager removeItemAtPath:thumbTrash error:NULL];

        }


        //Save the context.
        //NSError *error;
        //if (![managedObjectContext save:&error]) {
            /*
             Replace this implementation with code to handle the error appropriately.

             abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
             */
        // NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        // abort();
        //}

    }

}


- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    [super setEditing:editing animated:animated];
    if (!editing) {
        //save here
        NSError *error;
        BOOL isSaved = [managedObjectContext save:&error];
        NSLog(@"isSaved? %@ ======================================", (isSaved ? @"YES" :@"NO ") );
    }
}


//Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
    //this implementation is from here: http://www.cimgf.com/2010/06/05/re-ordering-nsfetchedresultscontroller/

    NSMutableArray *things = [[fetchedResultsController fetchedObjects] mutableCopy];

    //Grab the item we're moving.
    NSManagedObject *thing = [fetchedResultsController objectAtIndexPath:fromIndexPath];

    //Remove the object we're moving from the array.
    [things removeObject:thing];
    //Now re-insert it at the destination.
    [things insertObject:thing atIndex:[toIndexPath row]];

    //All of the objects are now in their correct order. Update each
    //object's displayOrder field by iterating through the array.


    int i = 0;
    for (NSManagedObject *mo in things)
    {
        [mo setValue:[NSNumber numberWithInt:i++] forKey:@"order"];
    }


    NSLog(@"things: %@", things);
    [things release], things = nil; 

    //reordering = YES;
    //NSLog(@"moveRowAtIndexPath: IS reordering");
    //NSError *error;  
    //[managedObjectContext save:&error];   




}



#pragma mark -
#pragma mark Table view delegate
/**
 Delegate methods of NSFetchedResultsController to respond to additions, removals and so on.
 */

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {

    //The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    NSLog(@"controllerWillChangeContent: BeginUpdates");

    [self.tableView beginUpdates];

    beginUpdatesCount++;
    NSLog(@"====================beginUpdates was just incremented");
    NSLog(@"beginUpdatesCount %d", beginUpdatesCount);
    NSLog(@"endUpdatesCount   %d", endUpdatesCount);

}


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

    NSLog(@"didChangeObject: %@", anObject);

    UITableView *tableView;
    tableView = self.tableView;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            NSLog(@"ResultsChangeInsert:");
            insert = YES;
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

        case NSFetchedResultsChangeDelete:
            NSLog(@"ResultsChangeDelete:");
            delete = YES;
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

            break;

        case NSFetchedResultsChangeMove:
            NSLog(@"ResultsChangeMove:");
            move = YES;
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationNone];
            break;

        default:
            NSLog(@"switch problem - default");
    }

}

- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {

    NSLog(@"didChangeSection:");
    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        }
}


- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {

    NSLog(@"didChangeContent");
    //The fetch controller has sent all current change notifications, so tell the table view to process all updates.
    NSLog(@"almost endUpdates==============================================");
    if(delete){
        NSLog(@"endUpdates delete");
        delete = NO;
    }
    if(move){
        NSLog(@"endUpdates move");
        move = NO;
    }
    if(insert){
        NSLog(@"endUpdates insert");
        insert = NO;
    }

    [self.tableView endUpdates];
    endUpdatesCount++;

    NSLog(@"====================endUpdates was just incremented");
    NSLog(@"endUpdatesCount   %d", endUpdatesCount);
    NSLog(@"beginUpdatesCount %d", beginUpdatesCount);

    NSLog(@"endUpdates finished");

}


#pragma mark -
#pragma mark Memory management

- (void)dealloc {
    NSLog(@"Dealloc Sentence");
    //[fliteEngine stopTalking];
    //[fliteEngine release];
    addButtonItem   = nil;
    playButtonItem  = nil;

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { 
        //It doesn't seem to get allocated because it's not set on the iPhone. 
        [addButtonItem  release];
        [playButtonItem release];
    }

    [story release];
    [fetchedResultsController release];

    [super dealloc];
}


@end
  • Dieser Fehler sagt, dass Sie gelöscht wird eine Zeile aber, dass Ihre Datenquelle noch Berichte die gleiche Anzahl von Zeilen (wenn es eins sein sollte weniger, da Sie gelöscht die Zeile). Wie es aussieht werden Sie dieses problem haben, wenn sentenceRetire.um null ist, da man nie entfernen Sie das Objekt aus der Datenquelle (aber Sie auch sonst tun).
  • Hochladen können Sie Ihr gesamtes Projekt für uns zu sehen?
  • Ich möchte lieber nicht hochladen, mein ganzes Projekt - welche Teile brauchen Sie? Ich habe versucht, alle relevanten Teile des Codes für dieses problem.
  • Ich bin mir nicht sicher, aber es wäre viel einfacher ausführen zu können, Sie dies und sehen Sie es im debugger....
  • Ja, ich Stimme zu - aber es ist nicht etwas, die ich bin bequem mit. Ich warf den ganzen UITableViewController in es jetzt, wenn das hilfreich ist, aber ich Schätze, es ist wirklich schwer zu Debuggen, ohne das Projekt.
  • Nur wenn ich half, Sie zu führen Sie zu beantworten. Ansonsten einfach hinzufügen und akzeptieren Sie Ihre eigenen Antwort, so dass andere sehen können, die richtigen sind. Danke aber!
  • Das ist schön, dass du es herausgefunden, das wurde hart!

Schreibe einen Kommentar