属性ViewDidLoad问题

时间:2012-07-03 18:16:53

标签: iphone objective-c ios core-data

我将NSManagedObjectContext从AppDelegate传递给ViewController。然后我获取Core Data的结果。但是,在ViewDidLoad方法中,NSManagedObjectContext始终为nil,而不是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;
}

3 个答案:

答案 0 :(得分: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

P-S:对不起打字错误


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

这很糟糕,因为您正在访问init中的view元素,强制立即加载xib AKA视图。 因此,在您可以为VC分配内容之前,您的viewDidLoad将被调用。 从init方法中删除所有与视图相关的代码并将其放在viewDidLoad中,您的VC应具有更正常的视图生命周期。 另请注意,在导航控制器中,如果发出内存警告,则可能会取消分配不在屏幕上的VC的视图。 并且在那个时候,当视图需要恢复生命时,init代码将不会再次调用,但是将再次调用viewDidload。

答案 1 :(得分:0)

如何将`NSManagedObjectContext'作为app委托的属性公开,只是在视图控制器中读取该属性?

答案 2 :(得分: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;
}