更新18/3#2.我已经开始计算beginUpdates和EndUpdates以确保它们是均匀的.就在出现异常之前,它们就会失去同步.不知道为什么.

更新18/3:我想我发现了问题,但我不确定我是否知道如何修复它.经过几个小时的实验,我发现当我在该会话期间在svc的主表视图中选择了多个项目时,我只能使应用程序崩溃.
当在主表视图中选择另一个项目时,详细信息表视图将获得一个新的对象集,并且如果它在更新/移动/删除/插入周期的中途,则称为刷新表.因此问题;我认为即使在detailviewcontroller上设置了新的故事对象,它也有更新旧故事对象的说明.

如何在详细视图中设置新故事之前完全处理动画/ coredata / tableview更新?我在setEditting == NO时保存对managedobjectContext的更改.我猜我需要制作一个自定义的setStory setter,它在接受新对象之前处理UITableView / CoreData集的所有更新?

在didSelectRowAtIndexPath中的svc的主tableview控制器上调用此代码:

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

我尝试删除动作不会动画的行时出现间歇性错误,应用程序基本上会挂起以下错误(尽管从CoreData集中删除了行).如果我在一个会话中从svc中的主表视图控制器中选择了多行,则会发生这种情况.

在一些谷歌搜索后,我认为它可能是一个问题(void)控制器:(NSFetchedResultsController *)控制器didChangeObject:(id)在更新后调用,以动画用户所做的更改.

我该如何修复这些间歇性错误?

> 16/3我试图真正简化我的代码.我删除了对托管对象上下文的所有调用并将它们放入setEditing,删除了多余的[self.tableview reloadData]和[self.tableview setneedsdisplay]并完全使’重新排序’bool无效(它仍然在代码中,但它总是设置为NO,所以没有区别). UITableView比以往任何时候都更加稳定,但我仍然设法在删除时出现间歇性错误(偶尔会添加) – 它似乎需要一段时间才能崩溃,但它仍然会.**
> 15/3:我认为它与CoreData / UITableView不同步有关–CoreData认为它比UITableView更少或更多
> CoreData集没有问题,它只是动画/ UI方面的东西(事情被删除)
>这是断断续续的,仅限于一些删除
>在来自railwayparade的一些帮助之后,我在didChangeObject中实现了NSFetchedResultsChangeMove:它修复了移动错误但没有修复删除错误.

谁能看到我错过的任何东西,或者我可以查看?很高兴提供更多信息,如果这有助于解决问题.

对于此处发布的淫秽数量的代码表示歉意.

错误:

CoreData: error: SerIoUs application error. An exception was caught
from the delegate of NSFetchedResultsController during a call to
-controllerDidChangeContent:. attempt to insert row 3 into section 0,but there are only 3 rows in section 0 after the update with 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,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],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,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,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: %@,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: %@,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

解决方法

更新18/3#3我读了 this question关于fetchedResultsController需要在创建一个新委托之前将其委托设置为nil.我放
detailViewController.fetchedResultsController = nil;
detailViewController.fetchedResultsController.delegate = nil;

在didselectrowatindexpath的SVC主视图中,问题已经停止.每次在主视图中选择一行时,RefreshTables都会创建一个新的fetchedResultsController,我认为即使选择了新的故事对象,它们仍然会干扰.

ios – UITableView删除/添加行导致CoreData:严重应用程序错误,如果在SplitViewController的MasterView中选择了另一个对象的更多相关文章

  1. ios – UITableView和Cell Reuse

    这是我的CustomCell类的init方法解决方法如果没有要显示的图像,则必须清除图像视图:

  2. ios – fetchedResultsController.fetchedObjects.count = 0但它充满了对象

    我正在使用相当标准的fetchedResultsController实现来输出tableView.在-viewDidLoad的最后,我正在进行第一次调用:这是我的fetchedResultsController:我的tableView方法:所以,问题是:在_fetchedResultsController.fetchedobjects.count的日志中等于0,但在视觉上tableView充满了对

  3. ios – UITableView在滚动时阻止重新加载

    或者你能想象一个防止这种行为的好方法吗?解决方法抱歉,我没有足够的声誉来添加评论,因此在单独的答案中回答您的上一个问题.-performSelector:withObject:afterDelay:延迟为0.0秒不会立即执行给定的选择器,而是在当前的RunloopCycle结束后和给定的延迟之后执行它.-performSelector:withObject:添加到当前Runloop循环中并执行.这与直接调用该方法相同.因此,使用-performSelector:withObject:afterDelay:

  4. ios – 在Swift中通过标记访问UITableViewCell内部的不同视图

    我正在尝试使用swift为iOS8制作应用程序.这里的目标是制作一种新闻源.此Feed显示来自用户的帖子,其遵循特定模式.我想过使用UITableView,其中每个单元格都遵循自定义布局.当我尝试访问其中的文本标签时出现问题.我尝试通过它的标签访问它,但是当我这样做时,整个应用程序崩溃了.报告的错误是“Swift动态转换失败”,我使用以下代码访问视图:难道我做错了什么?解决方法我认为问题是标签0.所有视图都是默认值0.所以尝试另一个标签值.

  5. ios – 如何实现`prepareForReuse`?

    解决方法尝试将此添加到您的MGSwipeTableCell.m:

  6. ios – 在UITableView上轻扫以删除以使用UIPanGestureRecognizer

    我使用以下代码将UIPanGuestureRecognizer添加到整个视图中:在主视图中我有一个UITableView,它有这个代码来启用滑动删除功能:只有RUNNING1打印到日志中,并且“删除”按钮不会显示.我相信其原因是UIPanGestureRecognizer,但我不确定.如果这是正确的,我该如何解决这个问题.如果这不正确,请提供原因并解决.谢谢.解决方法从document:Ifage

  7. viewWillAppear vs Viewdidload ios

    使用iOS导航应用程序的代码时,我遇到了麻烦:我在哪里可以为UITableView设置方法“initdata”?请帮帮我.解决方法您可以根据应用程序的需求放置initData,如果您的表需要每次使用新数据加载数据,那么它应该在否则,如果表需要通过单个数据重新加载,该数据不会发生变化或者没有对数据执行任何编辑操作,则应使用

  8. ios tableView reloadRowsAtIndexPaths无效

    解决方法包裹它怎么样?希望这可以帮助.

  9. ios – 我的表视图在滚动时在SWIFT中重用所选单元格

    实例变量

  10. ios – 多个NSPersistentStoreCoordinator实例可以连接到同一个底层SQLite持久性存储吗?

    我读过的关于在多个线程上使用CoreData的所有内容都讨论了使用共享单个NSPersistentStoreCoordinator的多个NSManagedobjectContext实例.这是理解的,我已经使它在一个应用程序中工作,该应用程序在主线程上使用CoreData来支持UI,并且具有可能需要一段时间才能运行的后台获取操作.问题是NSPersistentStoreCoordinator会对基础

随机推荐

  1. iOS实现拖拽View跟随手指浮动效果

    这篇文章主要为大家详细介绍了iOS实现拖拽View跟随手指浮动,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  2. iOS – genstrings:无法连接到输出目录en.lproj

    使用我桌面上的项目文件夹,我启动终端输入:cd然后将我的项目文件夹拖到终端,它给了我路径.然后我将这行代码粘贴到终端中找.-name*.m|xargsgenstrings-oen.lproj我在终端中收到此错误消息:genstrings:无法连接到输出目录en.lproj它多次打印这行,然后说我的项目是一个目录的路径?没有.strings文件.对我做错了什么的想法?

  3. iOS 7 UIButtonBarItem图像没有色调

    如何确保按钮图标采用全局色调?解决方法只是想将其转换为根注释,以便为“回答”复选标记提供更好的上下文,并提供更好的格式.我能想出这个!

  4. ios – 在自定义相机层的AVFoundation中自动对焦和自动曝光

    为AVFoundation定制图层相机创建精确的自动对焦和曝光的最佳方法是什么?

  5. ios – Xcode找不到Alamofire,错误:没有这样的模块’Alamofire’

    我正在尝试按照github(https://github.com/Alamofire/Alamofire#cocoapods)指令将Alamofire包含在我的Swift项目中.我创建了一个新项目,导航到项目目录并运行此命令sudogeminstallcocoapods.然后我面临以下错误:搜索后我设法通过运行此命令安装cocoapodssudogeminstall-n/usr/local/bin

  6. ios – 在没有iPhone6s或更新的情况下测试ARKit

    我在决定下载Xcode9之前.我想玩新的框架–ARKit.我知道要用ARKit运行app我需要一个带有A9芯片或更新版本的设备.不幸的是我有一个较旧的.我的问题是已经下载了新Xcode的人.在我的情况下有可能运行ARKit应用程序吗?那个或其他任何模拟器?任何想法或我将不得不购买新设备?解决方法任何iOS11设备都可以使用ARKit,但是具有高质量AR体验的全球跟踪功能需要使用A9或更高版本处理器的设备.使用iOS11测试版更新您的设备是必要的.

  7. 将iOS应用移植到Android

    我们制作了一个具有2000个目标c类的退出大型iOS应用程序.我想知道有一个最佳实践指南将其移植到Android?此外,由于我们的应用程序大量使用UINavigation和UIView控制器,我想知道在Android上有类似的模型和实现.谢谢到目前为止,guenter解决方法老实说,我认为你正在计划的只是制作难以维护的糟糕代码.我意识到这听起来像很多工作,但从长远来看它会更容易,我只是将应用程序的概念“移植”到android并从头开始编写.

  8. ios – 在Swift中覆盖Objective C类方法

    我是Swift的初学者,我正在尝试在Swift项目中使用JSONModel.我想从JSONModel覆盖方法keyMapper,但我没有找到如何覆盖模型类中的Objective-C类方法.该方法的签名是:我怎样才能做到这一点?解决方法您可以像覆盖实例方法一样执行此操作,但使用class关键字除外:

  9. ios – 在WKWebView中获取链接URL

    我想在WKWebView中获取tapped链接的url.链接采用自定义格式,可触发应用中的某些操作.例如HTTP://我的网站/帮助#深层链接对讲.我这样使用KVO:这在第一次点击链接时效果很好.但是,如果我连续两次点击相同的链接,它将不报告链接点击.是否有解决方法来解决这个问题,以便我可以检测每个点击并获取链接?任何关于这个的指针都会很棒!解决方法像这样更改addobserver在observeValue函数中,您可以获得两个值

  10. ios – 在Swift的UIView中找到UILabel

    我正在尝试在我的UIViewControllers的超级视图中找到我的UILabels.这是我的代码:这是在Objective-C中推荐的方式,但是在Swift中我只得到UIViews和CALayer.我肯定在提供给这个方法的视图中有UILabel.我错过了什么?我的UIViewController中的调用:解决方法使用函数式编程概念可以更轻松地实现这一目标.

返回
顶部