Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/44.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone NSFetchedResultsController不';t在启动后更新UITableView_Iphone_Ios_Objective C_Uitableview_Nsfetchedresultscontroller - Fatal编程技术网

Iphone NSFetchedResultsController不';t在启动后更新UITableView

Iphone NSFetchedResultsController不';t在启动后更新UITableView,iphone,ios,objective-c,uitableview,nsfetchedresultscontroller,Iphone,Ios,Objective C,Uitableview,Nsfetchedresultscontroller,我有一个简单的基于UIManagedDocument的核心数据应用程序。我对iOS编程还不熟悉,但我几乎还没有起步,我被卡住了。我将人员NSManagedObject存储在核心数据中。当我第一次启动应用程序时,没有任何条目,但如果我滑动一个模态VC并将其关闭,它们会神奇地出现。我的设计松散地基于iTunes U/Sanford课程中的“Photomania”应用程序,但使用单例CoreDataStore对象来处理managedObjectContext。这是我的CoreDataStore的代码:

我有一个简单的基于UIManagedDocument的核心数据应用程序。我对iOS编程还不熟悉,但我几乎还没有起步,我被卡住了。我将人员NSManagedObject存储在核心数据中。当我第一次启动应用程序时,没有任何条目,但如果我滑动一个模态VC并将其关闭,它们会神奇地出现。我的设计松散地基于iTunes U/Sanford课程中的“Photomania”应用程序,但使用单例CoreDataStore对象来处理managedObjectContext。这是我的CoreDataStore的代码:

+ (CoreDataStore *)sharedStore
{
    static CoreDataStore *sharedStore = nil;
    if (!sharedStore)
        sharedStore = [[super allocWithZone:nil] init];

    return sharedStore;
}

+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    return [self sharedStore];
}

- (NSManagedObjectContext *)getContext
{
    NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory
                                                         inDomains:NSUserDomainMask] lastObject];
    url = [url URLByAppendingPathComponent:@"dbDocument"];
    UIManagedDocument *document = [[UIManagedDocument alloc] initWithFileURL:url];

    if (![[NSFileManager defaultManager] fileExistsAtPath:[url path]]) {
        NSLog(@"No file exists...");
        [document saveToURL:url forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
            NSLog(@"Document saveForCreating completionHandler invoked. Success: %hhd", success);
            if (success) {
                self.managedObjectContext = document.managedObjectContext;
                NSLog(@"Got context for created file!!");
            }
        }];
    } else if (document.documentState == UIDocumentStateClosed) {
        NSLog(@"Document state is closed. documentState == %u", document.documentState);
        [document openWithCompletionHandler:^(BOOL success) {
            NSLog(@"Document opening success: %hhd", success);
            if (success) {
                self.managedObjectContext = document.managedObjectContext;
                NSLog(@"Got context for now-opened file!!");
            }
        }];
    } else {
        self.managedObjectContext = document.managedObjectContext;
        NSLog(@"Got context for already-opened file!!");
    }

    return self.managedObjectContext;
}
下面是PeopleListViewController的代码:

- (void)setManagedObjectContext:(NSManagedObjectContext *)managedObjectContext
{
    _managedObjectContext = managedObjectContext;
    if (managedObjectContext) {
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
        request.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name"
                                        ascending:YES
                                        selector:@selector(localizedCaseInsensitiveCompare:)]];
        request.predicate = nil;  // all Persons
        self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:managedObjectContext sectionNameKeyPath:nil cacheName:nil];
    } else {
        self.fetchedResultsController = nil;
    }
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (!self.managedObjectContext)
        [self setManagedObjectContext:[[CoreDataStore sharedStore] getContext]];
}
这是发射后立即产生的结果:

这是模态VC:

这是在解除模式VC(点击取消)后:


我曾尝试在managedObjectContext上使用performFetch,甚至将其延迟到核心数据文档报告它被打开之后。什么都不管用。任何帮助都将不胜感激。

粗略地看一下您的代码,我注意到您正在异步创建上下文。这很好,但是当上下文准备好时,您需要通知表视图控制器并让它调用reloadData


数据存储中的完成处理程序需要在表视图控制器上设置上下文属性。

NSFetchedResultsController
不会神奇地更新您的表视图。我发现Photomania有点复杂,因为像CoreDataViewController这样的辅助类很少。因此,只能通过调用
reloadData
方法或使用一对
beginUpdates
-
endUpdates
来重新加载tableVew。和
NSFetchedResultsController
只能通过调用
performFetch:
方法进行更新。 我通常使用
NSManagedObjectContext
getter:

- (NSFetchedResultsController*)fetchedResultsController
{
    if (!_fetchedResultsController)
    {
        NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"some entity name"];
        fetchRequest.predicate = [NSPredicate predicateWithFormat:@"some predicate"];
        fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]];
        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.context sectionNameKeyPath:@"name" cacheName:nil];
        _fetchedResultsController.delegate = self;
        NSError* error;
        [_fetchedResultsController performFetch:&error];
        if (error)
        {
            NSLog(@"Fetch ERROR. %@", error);
        }
    }
    return _fetchedResultsController;
}
在这里,我将
nsfetechedresultscoontrollerdelegate
设置为self。和
performFetch:
获取数据。我了解代表的方法:

- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller
{
    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController*)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
    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)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath*)newIndexPath
{
    UITableView *tableView = self.tableView;

    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self configureCell:[tableView cellForRowAtIndexPath:indexPath]
                    atIndexPath:indexPath];
            break;

        case NSFetchedResultsChangeMove:
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
                             withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController*)controller
{
    [self.tableView endUpdates];
}
-(void)controllerWillChangeContent:(NSFetchedResultsController*)控制器
{
[self.tableView开始更新];
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeSection:(id)sectionInfo
atIndex:(nsInteger)ChangeType:(NSFetchedResultsChangeType)类型的节索引
{
开关(类型)
{
案例NSFetchedResultsChangesInsert:
[self.tableView insertSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet IndexSetWithiIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)控制器:(NSFetchedResultsController*)控制器didChangeObject:(id)一个对象
atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)类型
newindepath:(nsindepath*)newindepath
{
UITableView*tableView=self.tableView;
开关(类型)
{
案例NSFetchedResultsChangesInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeDelete:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
案例NSFetchedResultsChangeUpdate:
[self-configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexath];
打破
案例NSFetchedResultsChangeMove:
[tableView DeleteRowsatindExpath:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
打破
}
}
-(void)controllerDidChangeContent:(NSFetchedResultsController*)控制器
{
[self.tableView endUpdates];
}

我在
视图的末尾添加了一个
performFetch:
将出现
,但结果是相同的
BeginUpdate
/
EndUpdate
不起作用,因为它是应用程序启动时。尚未进行任何更新。@LouValencia,请尝试在
fetchedResultsController
setter中使用
performFetch:
。因此,您将在必要时执行
蚀刻:
,例如,在
行数部分:
中。如果您的存储将发生更改,
NSFetchedResultsControllerDelegate
方法将更新您的TableView我将如何执行此操作。我肯定这是需要在完成处理程序中进行的操作,但我不确定该如何进行。这听起来可能是个问题。我做了一个测试,发现
[fetchedObjects count]
最初是0,然后在取消模式VC后是5。