Iphone 如何在RootViewController之外的另一个视图上加载核心数据?
除了AppDelegate中的代码外,我的核心数据和应用程序基本正常工作。我遇到的问题代码如下:Iphone 如何在RootViewController之外的另一个视图上加载核心数据?,iphone,cocoa-touch,core-data,ios4,uiviewcontroller,Iphone,Cocoa Touch,Core Data,Ios4,Uiviewcontroller,除了AppDelegate中的代码外,我的核心数据和应用程序基本正常工作。我遇到的问题代码如下: - (void)applicationDidFinishLaunching:(UIApplication *)application { RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain]; tableController
- (void)applicationDidFinishLaunching:(UIApplication *)application {
RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
[tableController release];
[window addSubview: [self.navigationController view]];
[window makeKeyAndVisible];
}
我不想让managedObjectContext在启动时成为根视图控制器。我想让它成为另一个视图控制器。但是,如果我将类更改为我需要的视图控制器,它会在应用程序启动时加载该视图控制器,这不是我想要做的。我仍然希望启动根视图,但我希望能够加载其他视图控制器的核心数据上下文。我真的很困惑如何解决这个问题。到目前为止,我已经花了两天的时间试图找到一种方法来解决这个问题,但还没有找到运气。任何帮助都将不胜感激
此外,如果我在appdelegate didfinishlaunching中遗漏以下内容:
RootViewController *tableController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
[tableController release];
我得到这个错误:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'Hello'
编辑:
以下是实体代码:
- (void)viewDidLoad {
[super viewDidLoad];
self.title = @"Lap Times";
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addTime:)];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
[self fetchRecords];
}
- (void)addTime:(id)sender {
addTimeEvent *event = (addTimeEvent *)[NSEntityDescription insertNewObjectForEntityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];
[event setTimeStamp: [NSDate date]];
NSError *error;
if (![managedObjectContext save:&error]) {
// This is a serious error saying the record could not be saved.
// Advise the user to restart the application
}
[eventArray insertObject:event atIndex:0];
[self.tableView reloadData];
}
- (void)fetchRecords {
// Define our table/entity to use
NSEntityDescription *entity = [NSEntityDescription entityForName:@"addTime" inManagedObjectContext:self.managedObjectContext];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
// Define how we will sort the records
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[request setSortDescriptors:sortDescriptors];
[sortDescriptor release];
// Fetch the records and handle an error
NSError *error;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (!mutableFetchResults) {
// Handle the error.
// This is a serious error and should advise the user to restart the application
}
// Save our fetched data to an array
[self setEventArray: mutableFetchResults];
[mutableFetchResults release];
[request release];
}
另外,如果我使用自己的appdelegate(称为MyAppDelegate)
MyAppDelegate *tableController = [[MyAppDelegate alloc] initWithStyle:UITableViewStylePlain];
tableController.managedObjectContext = [self managedObjectContext];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:tableController];
我得到以下错误:
Object cannot be set- either readonly property or no setter found
除了名称之外,RootViewController没有什么神奇之处。只要这些视图控制器配置正确,就可以对其进行重命名或与任何其他视图控制器进行交换。您可能需要使用RootViewController并相应地调整新的视图控制器
那就是说我不明白你想做什么。您可能想发布不起作用的代码。我看不出您采用的原始方法有什么问题?您基本上是在应用程序委托中创建
managedObjectContext
,并通过赋值将其传递给tableController
另一种方法是让viewController从应用程序委托“询问”managedObjectContext。因此,您仍然可以将CoreData方法放在AppDelegate中,并在希望获取上下文引用的地方使用以下方法。由于managedObjectContext是在请求时延迟加载的,因此只有在您第一次访问应用程序委托中的managedObjectContext
方法时才会实例化它
AppDelegate *theDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
self.managedObjectContext = theDelegate.managedObjectContext;
PS1:显然,你需要用正确的应用程序名称替换AppDelegate
PS2:进行更改时出现错误的原因是没有可供CoreData使用的上下文。如果
+entityForName:
出现异常,您应该在+entityForName:
周围发布代码
如果我不得不猜测,我会说您的代码如下所示:
entity = [NSEntityDescription entityForName:@"Hello"
inManagedObjectContext:managedObjectContext];
^^^^^^^^^^^^^^^^^^^^
这意味着您正在使用managedObjectContext,而不使用getter。如果第一次需要,getter会使用延迟加载来加载上下文。我打赌managedObjectContext此时为零。使用调试器检查这一点 然后像这样更改行:
entity = [NSEntityDescription entityForName:@"Hello"
inManagedObjectContext:self.managedObjectContext];
^^^^^^^^^^^^^^^^^^^^^^^^^
由于此调用,当包含关于rootviewcontroller的四行代码时,该代码起作用:
tableController.managedObjectContext = [self managedObjectContext];
^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果为nil,则将创建上下文。延迟加载
[self-managedObjectContext]
与self.managedObjectContext
但我的帖子中的所有内容都是猜测,因为您没有包括+entityForName:inManagedObjectContext:的代码,实际上,他传递managedObjectContext的方法比向AppDelegate请求上下文要好。但只有当应用程序需要重构以使用不同的上下文进行插入时,人们才会意识到这一点。或者控制器是否将用于其他应用程序。我完全同意!让控制器请求上下文会在两者之间创建不必要的耦合。如果我使用上面的示例代码,我会得到以下错误:无法设置对象-找不到只读属性或设置器。您需要在视图控制器界面
@属性中为managedObjectContext创建属性(非原子,保留)NSManagedObjectContext managedObjectContext如果我使用tableController.managedObjectContext=[self-managedObjectContext],请确保应用程序委托managedObjectContext未标记为@private(也在接口文件中);使用我的rootviewcontroller,当我尝试从rootviewcontroller查看我的另一个viewcontroller时,我在调试器中遇到以下错误:由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“+entityForName:找不到实体名称“addTime”的NSManagedObjectModel”