1

ユーザーテーブルと女の子テーブルとgirls_resultテーブルがあります。

基本的に、エンティティに1人のユーザーのみが必要でUSERあり、そのUSERはデバイスの所有者であり、必要になるたびに同じUSERを呼び出します。

USERは複数の女の子を持つことができ、女の子は複数の結果を持つことができます。
データ・モデル: USER <------>>GIRLS<-------->>GIRLS_RESULTS

そこで、user_deviceid属性をUSERエンティティに追加し、シングルトンクラスを作成して、ユーザーに一意の番号を設定し、必要なときに呼び出すことができるようにしました。同じUUIDを持つ複数のユーザーオブジェクトが作成されないようにしたい。

@implementation SingletonClass

@synthesize singletonManagedObjectContext=_singletonManagedObjectContext;
@synthesize userIS=_userIS;

+ (SingletonClass *)sharedInstance
{
    static SingletonClass *sharedInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sharedInstance = [[SingletonClass alloc] init];
        // Do any other initialisation stuff here
    });
    return sharedInstance;
}

- (id)init {
    if (self = [super init]) {

        // set a singleton managed object context
        _singletonManagedObjectContext=self.singletonManagedObjectContext;

        //set only one user based on unique device id, so all tables will belong to that user
        NSManagedObjectContext *context = _singletonManagedObjectContext;

        //how to make sure that _userIS is the same user all the time???

        if (_userIS.user_deviceid == [self newUUID]) {
            NSLog(@"user dvice id matches");
        }
        else{
            _userIS.user_deviceid=[self newUUID];
        }


    }
    return self;
}

- (NSString *)newUUID
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return (NSString *)CFBridgingRelease(string);
} 

では、USERエンティティに1つのUSERのみが作成され、その特定のUSERを毎回使用できるようにするにはどうすればよいですか?

============回答の編集============受け入れられた回答に基づく以下のクラスを作成しましたが、正常に機能します

#import "CheckUser.h"
#import "USER.h"
#import "SingletonClass.h"

@implementation CheckUser


- (USER *)checkandreturnUser
{
    SingletonClass *sharedInstance = [SingletonClass sharedInstance];
    NSManagedObjectContext *context = sharedInstance.singletonManagedObjectContext;
    // Fetch Form Object
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"USER"
                                        inManagedObjectContext:context]];
    USER *user;
    NSError *error = nil;
    NSArray *userArray = [context executeFetchRequest:fetchRequest error:&error];
    NSLog(@"user array count %i",[userArray count]);
    if (userArray == nil) {
        NSAssert(0, @"There was an error fetching user object");
        userArray = [NSArray array];
    }
    // If user doesn't exist create it
    if ([userArray count] > 0) {
        NSAssert([userArray count] == 1, @"Expected one user but there were more");
        user = [userArray objectAtIndex:0];
    } else {
        //Create user object
        user = [NSEntityDescription insertNewObjectForEntityForName:@"USER"
                                             inManagedObjectContext:context];
        user.user_deviceid=[self newUUID];
        // maybe save here?
        if (![context save:&error]) {
            NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
        }
    }


    return user;
}
- (NSString *)newUUID
{
    CFUUIDRef theUUID = CFUUIDCreate(NULL);
    CFStringRef string = CFUUIDCreateString(NULL, theUUID);
    CFRelease(theUUID);
    return (NSString *)CFBridgingRelease(string);
}
4

3 に答える 3

8

Core Data は、シングルトン エンティティの考え方をサポートしていません。データ ストアにエンティティのインスタンスを 1 つだけ保持する場合は、複数のインスタンスを作成しないようにアプリを作成する必要があります。

その理由は、単純に、データ ストアの概念に合わない奇抜な提案だからです。インスタンスが 1 つしかない場合は、そのインスタンスに Core Data を使用する必要はありません。シングルトン データをユーザー デフォルトまたはカスタム ファイルに保存します。それをデータストアに入れることはあまり意味がありません。それらの関係が何であるかを常に知っているため、オブジェクトと他のオブジェクトとの間の関係は必要ありません。それらは構成可能ではなく、検索する必要がないため、存在する必要はありません。

于 2013-01-25T17:16:38.350 に答える
1

最も簡単な解決策は、複数の USER を作成していないことを確認することです。1 つのユーザー エンティティを作成したら、停止します。

[self newUUID]常に異なる値を返すため、_userIS.user_deviceid == [self newUUID]常にNO

アクセサーを使用します_userIS

- (NSManagedObject *)user
{
  if (_userIS) {
    return _userIS;
  }

  NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
  [fetchRequest setEntity:[NSEntityDescription entityForName:@"user" 
                                      inManagedObjectContext:_singletonManagedObjectContext]];
  NSError *error = nil;
  NSArray *userArray = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
  if (userArray == nil) {
    NSAssert(0, @"There was an error fetching user object");
    userArray = [NSArray array];
  }
  // If user doesn't exist create it
  if ([userArray count] > 0) { 
    NSAssert([userArray count] == 1, @"Expected one user but there were more");
    _userIS = [userArray objectAtIndex:0];
  } else {
    //Create user object
    _userIS = [NSEntityDescription insertNewObjectForEntityForName:@"user" 
                                                 inManagedObjectContext:_singletonManagedObjectContext];
    _userIS.user_deviceid=[self newUUID];
    // maybe save here?
  }
  [_userIS retain]; // Non-ARC only
  return _userIS;
}

また、ルート オブジェクトを持つことは珍しくなく、Model-View-Controller-Store パターンの一部であることにも言及する価値があります。

于 2013-01-25T17:19:50.577 に答える
0

- (id)initWithEntity:(NSEntityDescription *)entity insertIntoManagedObjectContext:(NSManagedObjectContext *)contextではなく、オーバーライドする必要がありますinit。モデルオブジェクト名がUserであるとすると、次のようになります。

- (id)          initWithEntity:(NSEntityDescription *)entity 
insertIntoManagedObjectContext:(NSManagedObjectContext *)context
    static User * _Singleton = nil;
    if (!_Singleton)
    {
        self = [super initWithEntity:entity 
      insertIntoManagedObjectContext:context];
    }
    return self;
于 2013-01-25T17:25:20.497 に答える