2012-01-16 1 views
0

私は脳を荒らしています。シングルトンクラスDataLoader - AppDelegateのコアデータから値を設定しますが、他のクラスのDataLoader変数にはアクセスできません

基本的に、私は、AppDelegateクラスのsqlite dbからDataLoaderというシングルトンクラスの共有変数にデータをロードするようにコアデータを設定しました。

私はGameSceneというメインクラスも持っています。GameSceneはDataLoaderデータも使用します。私がやろうとしています何

次のとおりです。データローダーシングルトンクラス変数(特にNSMutableArrayの)

    • (バックグラウンドスレッドを使用して)DBからの負荷データとストア結果このように、シーンがメインメニューエリアに移動している間にデータがロードされる
    • GameSceneクラスでは、DataLoaderシングルトンに格納されているデータにアクセスし、このデータをゲームで使用しようとします。

    私の問題は、私は、私はAppDelegateクラスのオブジェクトを格納することがわかりますが、私はGameSceneクラスのオブジェクトを返すことができていないようだということです。通常、EXC_BAD_ACCESSエラーで終了します。

    私は実際に何か似たようなものやアイデアがある場合は、いくつかの例を探しています。

    コードサンプルが必要な場合は、お知らせください。

    ありがとう、 Pras。

    * EDIT - コードスニペット *

    DataLoader.h

    #import <Foundation/Foundation.h> 
    #import "cocos2d.h" 
    
    @interface DataLoader : NSObject { 
    
    } 
    
    //setup singleton 
    +(DataLoader *) sharedDataLoader; 
    @property (nonatomic, retain) NSMutableArray * veHint;//2 characters 
    

    DataLoader.m

    #import "DataLoader.h" 
    #import <CoreData/CoreData.h> 
    
    @implementation DataLoader 
    @synthesize veHint; 
    
    static DataLoader * myDataLoader = nil; 
    
    +(DataLoader *) sharedDataLoader{ 
    
        if(myDataLoader == nil){ 
         myDataLoader = [[[DataLoader alloc]init]retain]; 
        } 
        return myDataLoader; 
    } 
    
    -(id) init 
    { 
        if((self = [super init])){ 
         veHint = [NSMutableArray arrayWithCapacity:10]; 
        } 
        return self; 
    } 
    

    AppDelegate.mm

    #import "AppDelegate.h" 
    #import "GameScene.h" 
    #import "RootViewController.h" 
    #import "Word.h" 
    #import "DataLoader.h" 
    -(void) applicationDidFinishLaunching:(UIApplication*)application 
    { 
    //other standard stuff here... 
    
    //my load data method using data loader 
    [self getRandomData]; 
    
    //other standard stuff here... 
    
    // Run the intro Scene 
    [[CCDirector sharedDirector] runWithScene: [GameScene node]]; 
    } 
    
    //other standard methods for Core Data 
    
    //Random data loader 
    
    -(void) fetchRandomData: (NSString *) searchInteger{ 
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
        NSLog(@"fetching random data for word size: %@", searchInteger); 
    
        NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
        NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Word" inManagedObjectContext:managedObjectContext]; 
        [request setEntity:entity]; 
    
        //setup predicate 
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY %K == %@", @"size", searchInteger]; 
        [request setPredicate:predicate]; 
    
        NSError *error = nil; 
        NSArray *fetchResults = [managedObjectContext executeFetchRequest:request error:&error]; 
        NSLog(@"fetch results count = %i", [fetchResults count]); 
        [request release]; 
    
        NSMutableArray * results = [NSMutableArray arrayWithCapacity:10]; 
        NSMutableArray * fetchedIndexes = [NSMutableArray arrayWithCapacity:10]; 
        //get the total count, randomize selection of 10 results from the list 
    
        int j = 0; 
        while (j<10) { 
         int index = arc4random() % [fetchResults count]; 
         //get only unique values 
         if ([fetchedIndexes containsObject:[NSNumber numberWithInt:index]] == false)  { 
          [fetchedIndexes addObject:[NSNumber numberWithInt:index]]; 
    
          Word * word = (Word *) [fetchResults objectAtIndex:index]; 
          //NSLog(@"j = %i, index = %i, wordsize = %@, wordstring = %@",j, index, word.size, word.wordString); 
          [results addObject:word]; 
          j++; 
    
         } 
        } 
        //set dataloader 
        [[DataLoader sharedDataLoader] setVeHint:results]; 
    
        [pool drain]; 
    
    } 
    

    また、EXC_BAD_ACCESSがAppDelegate.mmの[pool drain]呼び出しにあることに言及する必要があります。

    ご協力いただきありがとうございます。

  • +0

    はい、サンプルコードは問題を明確にし、問題を見つけやすくします。 –

    +1

    多くのことが人生で間違っている可能性があります...私はどれを選ぶかわかりません...-(あなたのシングルトンのデータにアクセスする方法と、シングルトンがどのように定義されているかを教えてください。 –

    +0

    こんにちは、お返事ありがとうございます。このコードはRay WenderlichのCore Dataチュートリアル([http://www.raywenderlich.com/934/core-data-tutorial]に非常によく似ています。私は、NSFetchRequestを含むメソッドgetRandomData()を持っています。このメソッドでは、フェッチされた結果がフィルタリングされ、この このCore Dataメソッドからの逸脱はごくわずかなので、質問に答えたかどうかわかりません [1]:http://www.raywenderlich.com/934/core-data-tutorial-getting-started – prazzledazzle

    答えて

    0

    問題はおそらくコードのどこかにあります(私はそれがメモリ/スコープ関連、あまりにも早いリリースのようなものだと思います)。すべてのデータを適切に「メモリ管理」している限り、データへのアクセス方法は重要ではありません。

    このようなデータ管理をどのように行うことができます。

    私は通常DataManagerそれに名前を付ける:

    データマネージャーを。私たちはあなたのシングルトン;-)

    と間違って何が起こっているのかを見つけることができるように時間

    #import <Foundation/Foundation.h> 
    
    @interface DataManager : NSObject { 
        NSDate *someDate; 
    } 
    
    @property (nonatomic, retain) NSDate *someDate; 
    
    +(DataManager*)sharedInstance; 
    - (void)loadSettings; 
    - (void)saveSettings; 
    
    @end 
    

    DataManager.m

    #import "DataManager.h" 
    
    static DataManager *dataManagerInstance; 
    
    @implementation DataManager 
    
    @synthesize someDate = _someDate; 
    
    // singleton method 
    +(DataManager*)sharedInstance { 
        if(!dataManagerInstance) { 
         dataManagerInstance = [[DataManager alloc] init]; 
        } 
        return dataManagerInstance; 
    } 
    
    - (void)saveSettings { 
        // save your data 
    } 
    
    - (void)loadSettings { 
        // load your data 
    } 
    

    私はあなたがアイデアを得た願っています...多分あなたは、いくつかのコードスニペットを投稿します

    更新:OK、コードスニペットを追加しました。問題は明らかに次の行にあります。

    [[DataLoader sharedDataLoader] setVeHint:results]; 
    

    veHintをresultsに設定しているため、DataLoaderのプライベート変数を上書きしています。そのようにしないでください。resultsがリリースされ、DataLoaderが参照を失うためです。

    [[DataLoader sharedDataLoader] setVeHint:[results retain]]; 
    

    あなたはこのようにデータローダーにそれを通過した後resultsを保持resultsのコピーを作成し、veHint

    または

    に要素を置く別のsetterメソッドを、書くべきいずれかしかし、にveHintを保持しているので、このソリューション(とあなたのもの)はメモリリークを作成し、それをあなたの代理人に上書きします明らかにveHintへの参照を失う)。

    +0

    シングルトンに関して、上のseptiで与えられたサンプルは、NSMutableArrayの変数とNSMutableArray内の特定の値を返すメソッドを持っていることを除いて、シングルトンDataLoaderクラスのコードとほぼ同じです。 – prazzledazzle

    +0

    私はこの問題が**あなたがどのように戻って**あなたが回っているオブジェクトを管理しているかと思います。あなたは本当にいくつかのコードをアップロードする必要があります;-) – tamasgal

    +0

    要求としてコードスニペットが追加されました - 遅れて申し訳ありません。 – prazzledazzle

    0

    デフォルトでコアデータはスレッドセーフではありません。複数のスレッドで使用する場合は、Apple's guidelinesに精通していることを確認してください。

    +0

    ありがとうございます。コアデータがシングルトンではないことは気にしない。実際、私はApp Delegateクラスからsqlite DBにアクセスするための標準メソッドを持っています。 DBからの結果フェッチを使用してシングルトンクラス内の変数を設定して、メインのゲームシーンがフィルタリングされたデータにアクセスできるようにしたいだけです。それが意味をなさないならば。 – prazzledazzle

    関連する問題