【问题标题】:How to refresh a TableView when data is inserted in the AppDelegate?在 AppDelegate 中插入数据时如何刷新 TableView?
【发布时间】:2011-06-22 19:55:39
【问题描述】:

要为小型 Iphone-App 预填充我的数据库,我会在 AppDelegate 中的 persistentStoreCoordinator 方法中检查 sqlite 文件是否已经存在。如果不是,我在创建数据库后将一些数据添加到表中。但是数据不应该直接显示在 RootViewController 中,而是显示在另一个 TableView 中,可以通过在 RootViewController 中按选项来访问。

问题是数据已保存但未显示在 TableView 中。但是如果终止并重新启动应用程序,数据就在那里。

我已将 managedObjectContext 从我的 appDelegate 传递到 RootViewController,然后从那里传递到 TableViewController。所以 managedObjectContext 到处都是一样的。

这是我预填充数据库的代码(在此示例中只有一个示例行):

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator_ != nil) {
    return persistentStoreCoordinator_;
}

NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"TestDBApp.sqlite"];

NSString *storePath = [storeURL relativePath];
BOOL noDb = false;

NSFileManager *fileManager = [NSFileManager defaultManager];
if( ![fileManager fileExistsAtPath:storePath]) {
    noDb = true;
}

NSError *error = nil;
persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}    

if( noDb) {
    noDb = false;
    [self populateDB];
}

return persistentStoreCoordinator_;

}

- (void) populateDB {
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Kunde" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"oxid" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Root"];
NSError *error = nil;
if (![aFetchedResultsController performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

[self insertNewKunde:aFetchedResultsController];

[self saveContext];

[aFetchedResultsController release];
[sortDescriptors release];
[sortDescriptor release];
[fetchRequest release];

}

- (void)insertNewKunde:(NSFetchedResultsController *)fetchedResultsController {

// Create a new instance of the entity managed by the fetched results controller.
NSManagedObjectContext *context = [fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];

// If appropriate, configure the new managed object.
[newManagedObject setValue:[[NSDate date] description] forKey:@"oxid"];
[newManagedObject setValue:@"Max" forKey:@"fname"];
[newManagedObject setValue:@"Mustermann" forKey:@"lname"];

// Save the context.
NSError *error = nil;
if (![context save:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

}

managedObjectContext 从 AppDelegate 传递到 RootViewController 为:

- (void)awakeFromNib {

RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];

rootViewController.managedObjectContext = self.managedObjectContext;

}

和另一个 TableViewController:

- (void)awakeFromNib {
kundenVC = [[KundenViewController alloc] initWithManagedObjectContext:self.managedObjectContext];

}

谁能帮我或给个提示?

我也尝试通过viewWillAppear-Method重新加载tableView。但没有效果。

【问题讨论】:

    标签: iphone objective-c core-data reload tableview


    【解决方案1】:

    很难猜测发生了什么,但我的直觉是,在实际创建 RootViewController 之前,您不会调用 self.populateDB。这意味着 RootViewController 看不到该数据,因为它没有被创建。 我可能是错的,但我猜你在 delegate 的 awakeFromNib 方法中的最后一行最终是通过 self.managedObjectContext -> persistentStoreCoordinator -> self.populateDB 调用 populateDB

    请尝试在 awakeFromNib 的顶部添加一行,如下所示:

    (void)awakeFromNib {
         NSManagedObjectContext *context = self.managedObjectContext;
    
         RootViewController *rootViewController = (RootViewController *)[navigationController topViewController];
    
         rootViewController.managedObjectContext = context;}
    

    这样我希望你的问题得到解决,因为 self.managedObjectContext 将调用 getter (- (NSManagedObjectContext)managedObjectContext;) 而不是字段。在里面(如果你使用生成的代码)有一个对 **persistentStoreCoordinator** 的 getter 的调用,它最终会调用你的 populateDB 方法。

    如果这不起作用,请继续在您的 populateDB 中设置一个断点。当调试器停止时,您应该会在方法调用堆栈中看到实际调用 populateDB 的位置,这可能有助于找出您的问题。

    -安迪

    【讨论】:

    • 感谢您的努力。由于工作繁重,我没有尝试过您的建议。但我注意到了你的回答,并会给你一个反馈。所以我恳求耐心。谢谢。
    • 嗯,我试过你的建议,但没有效果。然后我做了一个调试,在那里我找到了一个提示。当调用指针停留在我的 populateDB 时,我注意到 managedObjectContext 仍然为零。由于沮丧,我打开了一个新项目,在这里我做了以下事情:1)在persistentStoreCoordinator中,我检查了sqlite-File是否存在。如果不是,我将布尔标志设置为 true。 2)如果标志为真,我在 managedObjectContext 中调用了我的 populateDB。现在数据立即显示在调用的视图中。无论如何,我感谢安迪试图解决这个问题。抱歉 4 耽搁了。
    【解决方案2】:

    好吧,您回答问题时遗漏了重要的部分。什么是 [self saveContext] 以及如何在表格视图中显示记录。

    因为您的数据已保存,所以我假设此处给出的代码有效。我能做出的唯一猜测是在 NSManagedObjectContext 上使用 reset 然后重新获取。

    顺便说一句,我喜欢“insertNewKunde”,这似乎是新的德语语法;-)

    【讨论】:

    • saveContext 是在 Xcode 中使用 CoreData 框架创建新项目时生成的方法。记录的显示方式与标准 Xcode 模板中的一样。没有自定义单元格。和 Standard-Template 的 RootViewController 一样。
    • 我尝试在添加数据后重置 NSManagedObjectContext(在 populateDB 完成后的 persistentStoreCoordinator-方法中)。但没有效果。我应该在哪里重置 NSManagedObjectContext?
    • 也许我的方法是完全错误的。我想知道是否有其他方法可以预填充数据库。问题是我能够将数据保存在数据库中,但是无法识别获取这些数据的记录的表视图。此 tableView 位于 TableViewController 中,不能通过 appDelegate 直接访问。欢迎任何建议
    • 我使用我的程序创建了 SQL Lite DB,然后查找了 iPhone Simulator Application 的文件夹并从那里取出 SQL lite 文件并将其放入我的应用程序中进行加载。这就是我预先填充数据库的方式。
    • 通常自定义单元格是在“cellForRowAtIndexPath”方法中定义的,因此它们应该出现。
    猜你喜欢
    • 2013-12-25
    • 1970-01-01
    • 2017-09-22
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2017-12-13
    • 2015-10-03
    相关资源
    最近更新 更多