2011-02-13 59 views
3

我基本上有核心數據和應用程序正常工作,除了AppDelegate中的代碼。我有問題的代碼如下:如何在除RootViewController之外的另一個視圖上加載核心數據?

- (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經推出根視圖控制器。我想讓它成爲另一個視圖控制器。但是,如果我將類更改爲需要它的視圖控制器,它會在啓動應用程序時加載該視圖控制器,這不是我想要的。我仍然想啓動根視圖,但我想能夠加載我的其他視圖控制器的核心數據上下文。我很困惑如何解決這個問題。到目前爲止,我花了2天的時間試圖找到解決方法,但沒有運氣。任何幫助,將不勝感激。

另外,如果我離開了在的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 

回答

0

我不能看到你正在採取的原始方法的問題?您基本上在您的應用程序代理中創建managedObjectContext,並通過分配將其傳遞到tableController

解決這個問題的另一種方法是讓viewController從應用程序委託中「詢問」managedObjectContext。所以你仍然可以將你的CoreData方法放置在你的AppDelegate中,並在你想要獲取對上下文的引用時使用以下內容。由於managedObjectContext是根據請求延遲加載的,因此只有在您第一次訪問應用程序委託中的managedObjectContext方法時纔會實例化它。

AppDelegate *theDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate]; 
self.managedObjectContext = theDelegate.managedObjectContext; 

PS1:顯然你需要用App的正確名稱替換AppDelegate。

PS2:當您進行更改時出現錯誤的原因是CoreData無法使用上下文。

+0

其實他傳遞managedObjectContext的方法比要求更好上下文的AppDelegate。但是,只有當應用程序需要重構才能使用不同的上下文進行插入時,人們纔會意識到這一點。或者,如果控制器將用於不同的應用程序。 – 2011-02-13 10:03:48

+0

我完全同意!讓控制器詢問上下文會在兩者之間產生不必要的耦合。 – Rog 2011-02-13 10:11:21

0

有什麼魔力名稱旁邊的RootViewController的。只要這些視圖控制器配置正確,您就可以重新命名它,或者您可以與任何其他View Controller交換它。您可能需要使用RootViewController並相應地調整新的View Controller。

這就是說我不明白你想要做什麼。您可能想要發佈不起作用的代碼。

0

如果您得到+entityForName:的例外,您應該在+entityForName:附近發佈代碼。

如果我不得不作出一個猜測,我會說,你的代碼如下所示:

entity = [NSEntityDescription entityForName:@"Hello" 
        inManagedObjectContext:managedObjectContext]; 
              ^^^^^^^^^^^^^^^^^^^^ 

這意味着你使用的是managedObjectContext沒有消氣。如果第一次需要,getter使用延遲加載來加載上下文。
我敢打賭managedObjectContext在這一點上是零。使用調試器檢查了這一點。

,然後改變這樣的行:

entity = [NSEntityDescription entityForName:@"Hello" 
        inManagedObjectContext:self.managedObjectContext]; 
              ^^^^^^^^^^^^^^^^^^^^^^^^^ 

代碼的工作,當你有四個線對,因爲這個調用的RootViewController的:

tableController.managedObjectContext = [self managedObjectContext]; 
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

這將創造如果上下文是零。延遲加載。

[self managedObjectContext]相同self.managedObjectContext

,但一切都在我的崗位是一個猜測,因爲你不包括各地+ entityForName代碼:inManagedObjectContext:

相關問題