0

我将 NSManagedObjectContext 从 AppDelegate 传递给 ViewController。然后我从核心数据中获取结果。但是,NSManagedObjectContext 在 ViewDidLoad 方法中始终为零,而在 ViewDidAppear 方法中则不是。

我理解这两种方法之间的区别,但我认为我应该能够从 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;
}
4

3 回答 3

0

我没有足够的信息来给出我可以肯定的答案,但这是我的想法。

你写// This code crashings because my because my Context is nil上下文的地方实际上是“不是零”,但是你的 NSFetchedResultController 还没有被初始化并且仍然是nil

如果您可以在 viewDidAppear 中访问您的 NSFetchedResultController ,那是因为那是在您的代码中的 viewDidLoad 之后创建的。您可以在getter该属性或 ViewDidLoad 中移动 NSFetchedResultController 的创建。

我刚刚在 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

PS:抱歉错别字


这与您的解决方案/问题有关。

这很糟糕,因为您在 init 中访问视图元素会强制立即加载 xib AKA 视图。因此,您的 viewDidLoad 将在您将某些内容分配给您的 VC 之前被调用。从您的 init 方法中删除所有与视图相关的代码并将其放在 viewDidLoad 中,您的 VC 应该有一个更正常的视图生命周期。还要记住,在导航控制器中,如果出现内存警告,不在屏幕上的 VC 视图可能会被释放。在那些时候,当视图需要恢复生命时,初始化代码不会再次被调用,但 viewDidload 将再次被调用。

于 2012-07-03T20:00:17.680 回答
0

将“NSManagedObjectContext”作为应用程序委托的属性公开,然后在视图控制器中读取该属性怎么样?

于 2012-07-03T20:54:16.960 回答
0

这是我的问题的解决方案。我在所有方法中都使用了这个 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;
}
于 2012-07-03T21:56:35.453 回答