2

私はCoreDataに非常に慣れておらず、多くのチュートリアルに従おうとしていますが、それらのほとんどはすべてのCoreDataメソッドをAppDelegateに組み込んでいます。AppDelegateから離れて、カスタムデータモデルクラスを使用してこれらのメソッドを管理する方がよいことを読みました。

。という名前のすべてのデータを管理するためのカスタムクラスを作成しましたMyDataModel。ボイラープレートのコアデータコードを実装しました。私のViewControllerの1つに、CoreDataを使用していくつかのデータを実装する簡単な方法があります。

- (void)getProfile {
/*
 * getProfile
 */
    NSLog(@"%@", _Model.managedObjectContext);
    Users *user = (Users *)[NSEntityDescription insertNewObjectForEntityForName:@"Users" inManagedObjectContext:_Model.managedObjectContext];

    // Set Data
    [user setValue:@"John" forKey:@"fname"];
    [user setValue:@"Smith" forKey:@"lname"];
    NSError *error;
    [_Model.managedObjectContext save:&error];
}

ヘッダーファイルのコード:

#import <UIKit/UIKit.h>
#import "Users.h"
#import <CoreData/CoreData.h>
#import "DataModel.h"

@interface ProfileViewController : UIViewController

// CoreData Related
@property (strong, nonatomic) DataModel *Model;

// Instance Methods
- (void)updateProfileData;

// Core Data Method
- (void)getProfile;

@end

このメソッドは、ViewControllerのメソッドで呼び出されますviewDidLoad。これを実行すると、次のエラーが発生します。

'+entityForName: nil is not a legal NSManagedObjectContext parameter searching for entity name 'Users''

StackOverflowで同様の質問が役立つかもしれませんが、それでも実際の解決策がわかりません。

'+ entityForName:nilは有効なNSManagedObjectContextパラメーターではありません-コアデータ

そのスレッドから述べられた解決策は、彼がコンテキストをViewControllerに渡すことでした。これはどのように達成されますか?私はすでにそれをしていると思っていました。

編集DataModel.h::

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
#import "Workouts.h"
#import "sqlite3.h"

@interface DataModel : NSObject {
    sqlite3 *Database;
}

@property (nonatomic, strong) Workouts *currentWorkout;

// Core Data Properties
@property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
@property (nonatomic, strong) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, strong) NSPersistentStoreCoordinator *storeCoordinator;

+ (DataModel *)sharedInstance;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;

@end

DataModel.m

#import "DataModel.h"

@implementation DataModel

#pragma mark - Core Data

+ (DataModel *)sharedInstance {
   static DataModel *sharedModel = nil;
   static dispatch_once_t onceToken;

   dispatch_once(&onceToken, ^{
       sharedModel = [[DataModel alloc] init];
       //sharedInstance.storeCoordinator = [sharedInstance storeCoordinator];
       //sharedInstance.managedObjectContext = [sharedInstance managedObjectContext];
   });
   return sharedModel;
}

- (void)saveContext {
    NSError *error = nil;
    if (_managedObjectContext != nil) {
        if ([_managedObjectContext hasChanges] && ![_managedObjectContext save:&error]) {
            NSLog(@"error: %@", error.userInfo);
        }
    }
}

#pragma mark - Core Data Stack

- (NSManagedObjectContext *)managedObjectContext {

    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self storeCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        [_managedObjectContext setPersistentStoreCoordinator: coordinator];
    }
    return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"DataModel" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_storeCoordinator != nil) {
        return _storeCoordinator;
    }

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"model.sqlite"];

    NSError *error = nil;
    _storeCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:_managedObjectModel];
    if (![_storeCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }

    return _storeCoordinator;
}

#pragma mark Application's Documents Directory

- (NSURL *)applicationDocumentsDirectory {
return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

@end

更新:オブジェクトがであった理由を理解しました(null)。シングルトンメソッドを呼び出そうとしましたが、sharedInstance正しく呼び出されませんでした。ゲッターが呼び出されていて、ゲッターを呼び出し続けるループにスローされました。合成された変数_managedObjectContextとを正しく使用しました_storeCoordinator。オブジェクトはメモリを適切に割り当て、参照を返すようになりました。みんな助けてくれてありがとう。

4

2 に答える 2

4

Application Delegate で作成される Core Data Stack に問題はありません。これが事実であることをどこで読んだことがありますか。

管理オブジェクト コンテキストを取得するために Application Delegate を呼び出すことは、確かに悪い設計と見なされますが、ほとんどの人は、管理オブジェクト コンテキストへの参照を Application Delegate からそれを使用する他のビュー コントローラーに渡します。

于 2013-02-04T18:10:05.563 に答える
1

ばかげた質問: あなたのモデルは実際に DataModel という名前ですか?

于 2013-02-05T06:02:51.023 に答える