0

NSManagedObjectContext を AppDelegate から ViewController に渡しています。次に、Core Data から結果を取得しています。ただし、NSManagedObjectContext は ViewDidLoad メソッドでは常に nil ですが、ViewDidAppear メソッドではそうではありません。

2 つのメソッドの違いは理解していますが、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た場所は実際には「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

PS:誤字脱字すいません


これは、ソリューション/問題に対応するものです。

init でビュー要素にアクセスしているため、xib AKA ビューがすぐに読み込まれるように強制されているため、これは悪いことです。したがって、VC に何かを割り当てる前に、viewDidLoad が呼び出されます。ビューに関連するすべてのコードを init メソッドから削除し、それを viewDidLoad に配置すると、VC のビューのライフ サイクルがより正常になります。また、ナビゲーション コントローラーでは、メモリ警告が発生した場合、画面上にない VC のビューの割り当てが解除される可能性があることに注意してください。その際、ビューを元に戻す必要があるときに init コードが再度呼び出されることはありませんが、viewDidload は再度呼び出されます。

于 2012-07-03T20:00:17.680 に答える
0

「NSManagedObjectContext」をアプリ デリゲートのプロパティとして公開し、View Controller でそのプロパティを読み取るだけではどうでしょうか。

于 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 に答える