0

CLLocation Managerを使用して、移動するたびに誰かの場所を取得し、lat、lng、timestampをコアデータに保存し、それをテーブルビュータブに表示しようとしています。ただし、コンソールの出力は、このログをスローすることにより、managedObjectContextがnillであることを常に示しています。coredataproject[12478:11903] After managedObjectContext: <NSManagedObjectContext: 0x7248230>

これが私のAppDelgate実装ファイルの関連コードです

#import "AppDelegate.h"
#import "RootViewController.h"
#import "FirstViewController.h"



@implementation AppDelegate

@synthesize window;
@synthesize navigationController;


#pragma mark -
#pragma mark Application lifecycle

- (void)applicationDidFinishLaunching:(UIApplication *)application {

    // Configure and show the window.

     RootViewController *rootViewController = [[RootViewController alloc] initWithStyle:UITableViewStylePlain];

    NSManagedObjectContext *context = [self managedObjectContext];
    if (!context) {
        NSLog(@"Could not create context for self");
    }
    rootViewController.managedObjectContext = context;

    UINavigationController *aNavigationController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
    self.navigationController = aNavigationController;

    [window addSubview:[navigationController view]];
    [window makeKeyAndVisible];


}

/**
 applicationWillTerminate: saves changes in the application's managed object context before the application terminates.
 */
- (void)applicationWillTerminate:(UIApplication *)application {

    NSError *error;
    if (managedObjectContext != nil) {
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            // Handle the error.
        } 
    }
}

これがFirstViewController.Mコードで、場所を取得してコアデータの「イベント」エンティティに保存しています。

    - (void)viewDidLoad
{


    locationManager =[[CLLocationManager alloc] init];

    locationManager.delegate = self; 
    locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    locationManager.distanceFilter = kCLDistanceFilterNone;
    [locationManager startUpdatingLocation];


-(void) locationmanager: (CLLocationManager *) manager
        didUpdateToLocation: (CLLocation *) newLocation
        fromLocation: (CLLocation *) oldLocation
{


    CLLocation *location = [locationManager location];
    if (!location) {
        return;
    }

    /*
     Create a new instance of the Event entity.
     */
    RootViewController *rootviewcontroller = [RootViewController alloc];    
    Event *event = (Event *)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:rootviewcontroller.managedObjectContext];

    // Configure the new event with information from the location.
    CLLocationCoordinate2D coordinate = [location coordinate];
    [event setLatitude:[NSNumber numberWithDouble:coordinate.latitude]];
    [event setLongitude:[NSNumber numberWithDouble:coordinate.longitude]];



    // Should be the location's timestamp, but this will be constant for simulator.
    // [event setCreationDate:[location timestamp]];
    [event setTimeStamp:[NSDate date]];

    // Commit the change.
    NSError *error;

    if (![rootviewcontroller.managedObjectContext save:&error]) {
        NSLog(@"Save Error");
    }

    //RootViewController *rootviewcontroller = [RootViewController alloc];
    [rootviewcontroller.eventsArray insertObject:event atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [rootviewcontroller.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [rootviewcontroller.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];   

}  

そして最後に、コアデータの内容を取得して表示しようとしているRootViewControllerファイルがあります。このタブをクリックすると、managedObjectConsoleがnillであることがコンソールから通知されます。

- (void)viewDidLoad {

[super viewDidLoad];

if (managedObjectContext == nil) 
{ 
    managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]; 
    NSLog(@"After managedObjectContext: %@",  managedObjectContext);
}       
// Set the title.
self.title = @"Locations";

/*
 Fetch existing events.
 Create a fetch request; find the Event entity and assign it to the request; add a sort descriptor; then execute the fetch.
 */
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:managedObjectContext];
[request setEntity:entity];

// Order the events by time stamp, most recent first.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timeStamp" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[request setSortDescriptors:sortDescriptors];


// Execute the fetch -- create a mutable copy of the result.
NSError *error = nil;
NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
if (mutableFetchResults == nil) {
    NSLog(@"Mutable Fetch Results equals nill");
}

// Set self's events array to the mutable array, then clean up.
[self setEventsArray:mutableFetchResults];

}

テーブルデータがそこにあると、それを整理することでさらにいくつかのことを行っていますが、それが問題であるとは思いません。

ロケーションマネージャーからのロケーションデータが含まれている必要があるため、managedObjectContextに何も含まれない理由がわかりません。私はCoreデータにあまり精通していないので、おそらく単純に間違ったことをしているだけですが、洞察をいただければ幸いです。

4

1 に答える 1

1

あなたの間違いはdidUpdateToLocationメソッドにあります。そこで、RootViewControllerの新しいインスタンスを作成します。newLocationをCoreDataに保存し、そのためのMOC(RootViewControllerではない)が必要です。したがって、MOCをFirstViewControllerに渡す方法を見つける必要があります。AppDelegateで行ったのと同じように、または次のようにこれを行うことができます。

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

viewDidLoadでRootViewControllerのMOCをリセットするのはなぜですか?あなたはすでにapplicationDidFinishLaunchingでそれを渡しました!

NSFetchedResultsControllerテーブルビューにはを使用することをお勧めします。データの変更を自動的に検出し、必要に応じてテーブルをリロードします。デリゲートを正しく実装するだけです。これに関する役立つチュートリアルは次のとおりです。http ://www.raywenderlich.com/999/core-data-tutorial-how-to-use-nsfetchedresultscontroller

于 2012-04-15T21:24:57.593 に答える