我正在将 NSManagedObjectContext 从 AppDelegate 传递给 ViewController。 然后,我正在获取核心数据的结果。 但是,NSManagedObjectContext 在 ViewDidLoad 方法中始终为 nil,而在 ViewDidSeem 方法中则不然。
我了解这两种方法之间的区别,但我认为我应该能够从 ViewDidLoad 访问属性,我什至注意到在 Apple 的示例代码中,它们这样做。
我应该只是在ViewDidAppear中获取吗?
- (void)viewDidLoad
{
[super viewDidLoad];
// This code crashings because my because my Context is nil
NSError *error;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
exit(-1);
}
}
编辑:我像这样传递它
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
rootViewController.managedObjectContext = self.managedObjectContext;
UINavigationController *rootNav = [[UINavigationController alloc] initWithRootViewController:rootViewController];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:rootNav, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
如何将"NSManagedObjectContext"公开为应用程序委托的属性,并在视图控制器中读取该属性?
这是我问题的解决方案。 我在所有方法中都使用了这个 init 方法来设置导航标题和其他一些项目。 我把这个方法拿出来,在viewDidLoad中做了所有这些,问题就解决了。
如果有人对为什么这会导致问题有更多见解,我很想听听。
- (id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// UINavigationBar
self.navigationItem.title = @"List";
// UINavigationBar Button
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(add:)];
self.navigationItem.rightBarButtonItem = addButton;
}
return self;
}
我没有足够的信息来给出我可以确定的答案,但这是我的想法。
你写// This code crashings because my because my Context is nil
上下文实际上"不是零",但你的NSFetchedResultController还没有初始化,仍然nil
如果你在viewDidAppear中访问NSFetchedResultController,那是因为它是在代码中的viewDidLoad之后创建的。您可以将 NSFetchedResultController 的创建移动到该属性的getter
或 ViewDidLoad 中。
我刚刚在AppDelegate中编写了一个测试代码。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
listView *rootViewController = [[listView alloc] initWithNibName:@"listView" bundle:nil];
rootViewController.managedObjectContext = self.managedObjectContext;
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
在 UITableViewController 子类中
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.managedObjectContext)
{
NSLog(@"Managed object ic not nil");
}
}
输出为:testCoreDataLauchn[1690:207] Managed object ic not nil
P-S : 对不起,错别字
这是为了配合您的解决方案/问题。
这很糟糕,因为您正在访问 init 中的视图元素,强制立即加载 xib AKA 视图。因此,在将某些内容分配给VC之前,将调用您的viewDidLoad。从 init 方法中删除所有与视图相关的代码并将其放在 viewDidLoad 中,您的 VC 应该有一个更正常的视图生命周期。另请记住,在导航控制器中,如果发出内存警告,则屏幕上未显示的 VC 视图可能会被释放。在这段时间里,当视图需要恢复活力时,初始化代码不会再次被调用,但 viewDidload 将再次被调用。