件名:コアデータ、VCからプロパティを取得/設定できません。最も一般的な間違い?
このサイトを検索しましたが、必要な回答を得ることができませんでした(ただし、多くの良いヒントがあります)。この質問を投稿して、数週間前から抱えていた問題が解決することを願っています。はい、非常にイライラします、あなたはおそらくその気持ちを知っています!だからどんな助けも素晴らしいでしょう-ありがとう!:-)
Oveview:
iOS5.1プロジェクト。Core Dataが機能するようになりました(main.h/NSLogでテスト済み)が、他のView Controllerからエンティティプロパティ(データ)を取得および設定するのに問題があります。Xcodeは、AppDelegateで見つかった単一の「AppContent」を他のView Controllerから認識しますが、エンティティ名とそのプロパティは認識しません。
これに関して最も一般的な間違いは何ですか?
正しい場所にファイルをインポートするのを忘れたような気がします...
いくつかの詳細;
参考:Matt Campellが推奨する方法を使用しようとしています。この方法では、AppDelegateにシングルトンを作成し、アプリ全体で使用して、任意のView ControllerからmanagedObjectContextを操作し、データを取得してCoreDataに保存できます。エンティティとそのそれぞれのプロパティ。これは、次の2つのファイルをアプリにインポートすることで実行されます。
appContent.h
#import <Foundation/Foundation.h>
#import "Contest.h" // Root Entity in CD model
#import "Player.h"
@interface AppContent : NSObject
+(AppContent *)sharedContent;
@property(strong, readonly) id rootObject;
-(void)save;
-(void)rollback;
@end
appContent.m
#import "AppContent.h"
#import <CoreData/CoreData.h>
@interface AppContent()
-(NSURL *)dataStoreURL;
@property (nonatomic, strong, readonly) NSManagedObjectModel *managedObjectModel;
@property (nonatomic, strong, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
@property (nonatomic, strong, readonly) NSManagedObjectContext *managedObjectContext;
@end
@implementation AppContent
NSManagedObjectModel *_managedObjectModel;
NSPersistentStoreCoordinator *_persistentStoreCoordinator;
NSManagedObjectContext *_managedObjectContext;
id _rootObject;
static AppContent *singletonInstance = nil;
+ (AppContent *)sharedContent{
@synchronized(self){
if (singletonInstance == nil)
singletonInstance = [[self alloc] init];
return(singletonInstance);
}
}
- (NSURL *)dataStoreURL {
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
return [NSURL fileURLWithPath:[docDir stringByAppendingPathComponent:@"DataStore.sql"]];
}
- (NSManagedObjectModel *)managedObjectModel {
if (_managedObjectModel) {
return _managedObjectModel;
}
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
return _managedObjectModel;
}
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (_persistentStoreCoordinator) {
return _persistentStoreCoordinator;
}
NSError *error = nil;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self dataStoreURL]
options:nil
error:&error]) {
NSLog(@"Unresolved Core Data error with persistentStoreCoordinator: %@, %@", error, [error userInfo]);
}
return _persistentStoreCoordinator;
}
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext) {
return _managedObjectContext;
}
if ([self persistentStoreCoordinator]) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]];
}
return _managedObjectContext;
}
-(id)rootObject{
if(_rootObject)
return _rootObject;
// #warning Replace [CHANGE] with your root object entity name
NSString *entityName = @"Contest";
NSManagedObjectContext *context = [self managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName
inManagedObjectContext:context];
request.entity = entity;
NSArray *listOfObjects = [context executeFetchRequest:request
error:nil];
if([listOfObjects count] == 1){
_rootObject = [listOfObjects lastObject];
return _rootObject;
}
_rootObject = [NSEntityDescription insertNewObjectForEntityForName:entityName
inManagedObjectContext:context];
// Adding some testdata (only first time...)
// Contest
Contest *c = _rootObject;
c.name = @"Big Game 1";
// Players
Player *p1 = (Player *) [NSEntityDescription insertNewObjectForEntityForName:@"Player"
inManagedObjectContext:context];
p1.name = @"Player One";
[c addPlayersObject:p1];
Player *p2 = (Player *) [NSEntityDescription insertNewObjectForEntityForName:@"Player"
inManagedObjectContext:context];
p2.name = @"Player Two";
[c addPlayersObject:p2];
[self save];
return _rootObject;
}
-(void)save{
NSError *error = nil;
NSManagedObjectContext *context = [self managedObjectContext];
if([context hasChanges])
[context save:&error];
if(error)
NSLog(@"Warning: Error saving to data store. %@", error);
}
-(void)rollback{
NSManagedObjectContext *context = [self managedObjectContext];
if([context hasChanges])
[context rollback];
}
@end
モデルファイル(CDモデルエディタで作成)は次のとおりです。
Contest.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Player;
@interface Contest : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSSet *players;
@end
@interface Contest (CoreDataGeneratedAccessors)
- (void)addPlayersObject:(Player *)value;
- (void)removePlayersObject:(Player *)value;
- (void)addPlayers:(NSSet *)values;
- (void)removePlayers:(NSSet *)values;
@end
Contest.m
#import "Contest.h"
#import "Player.h"
@implementation Contest
@dynamic name;
@dynamic players;
@end
Player.h
#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@class Contest;
@interface Player : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Contest *contests;
@end
Player.m
#import "Player.h"
#import "Contest.h"
@implementation Player
@dynamic name;
@dynamic contests;
@end
これがビューコントローラです
ここでコアデータエンティティとそのプロパティを取得しようとしていますが、XcodeはappContentを参照していますが、それを認識せず、ビルド時に「プロパティプレーヤーが見つかりません」というエラーが表示されます...
コンテストPlayerVC.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
#import "AppContent.h"
@interface contestPlayerVC : UIViewController
@property (strong, nonatomic) IBOutlet UITextField *playerNameField;
@property (strong, nonatomic) IBOutlet UITextField *playerMailField;
@property (strong, nonatomic) IBOutlet UIButton *playerSaveButton;
@property (weak, nonatomic) AppContent *content;
// Test
// @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;
- (IBAction)playerChooseImage:(UIButton *)sender;
- (IBAction)dismissModal:(UIButton *)sender;
- (IBAction)hideKeyboard:(id)sender;
- (IBAction)playerSave:(UIButton *)sender;
@end
コンテストPlayerVC.m 問題がメソッドviewDidLoadにあるため、ホールファイルが表示されません...
#import "contestPlayerVC.h"
@interface contestPlayerVC ()
@end
@implementation contestPlayerVC
@synthesize playerNameField, playerMailField, playerSaveButton, content;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// Call 1 - seems to work ok
self.content = [AppContent sharedContent];
////// Call 2 - gives error, can't find property "player" - WHY?
// Trying to set textfield to CD Entity "Player" and it's property "name"
self.playerNameField.text = self.content.player.name;
NSLog(@"Player is: %@", self.content.player.name);
// Call 3 - works ok
NSLog(@"Content is: %@", self.content.description);
}
...
ヒントや提案はありますか?ありがとう!:-)
ところで:長い投稿について申し訳ありませんが、他の人がそれを理解するのに十分なほど私の問題を説明する方法についてはわかりません。あなたがそれをすべて読んだら-私は感銘を受けました、そしてあなたが私がこれを解決するのを手伝ってくれるなら私は本当に幸せです。おそらく私が完全に見逃したいくつかの基本的なこと。ありがとう ;-)