2012-01-16 56 views
0

我一直在纏着我的大腦,還有很多搜索,但目前還沒有運氣。Singleton類DataLoader - 從AppDelegate中的Core Data設置值,但無法訪問其他類中的DataLoader變量

基本上,我已經設置Core Data來將數據從我的AppDelegate類中的sqlite數據庫加載到名爲DataLoader的單例類中的共享變量中。

我也有一個名爲GameScene的主類,它也將使用DataLoader數據。

我所試圖做的是如下:

  • 負載從數據庫中的DataLoader單例類變量(特別是一個NSMutableArray)數據(使用後臺線程),並存儲結果
  • 這樣,數據在場景轉換到主菜單區域時加載
  • 在GameScene類中,我嘗試訪問存儲在DataLoader單例中的數據,並在遊戲中使用這些數據。

我的問題是,雖然我可以看到我存儲在AppDelegate類的對象,我似乎不能夠在GameScene類返回的對象。通常以EXC_BAD_ACCESS錯誤結束。

我真的在尋找一些類似的東西或者如果你有任何想法的例子。

如果您需要代碼示例,請告訴我。

謝謝, Pras。

* 編輯 - 代碼段 *

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

是,示例代碼將明確您的問題,並使其更容易找到問題。 – 2012-01-16 23:01:30

+1

這麼多的事情可以去錯在生活......我不知道該選哪一個...... ;-(你如何嘗試在你的單身進入電影數據,以及如何你單身的定義。你線程與安全這個單?這些信息將幫助我們來幫助你。 – 2012-01-16 23:01:40

+0

嗨,大家好,感謝您的快速回復。該代碼是非常相似的雷Wenderlich的核心數據教程([http://www.raywenderlich.com/934/core-data-tutorial我有一個sqlite數據庫,它被加載了,然後我有一個方法getRandomData(),它包含了NSFetchRequest,在這個方法中,我獲取的結果被過濾了,這個是我設置的數據加載器的NSMutableArray變量 有從這個核心數據的方法非常小的偏差,所以我不知道如果回答您的問題 [1]:?http://www.raywenderlich.com/934 /核心數據教程工具入門 – prazzledazzle 2012-01-17 22:59:27

回答

0

該問題可能在代碼中的某處(我認爲它是內存/範圍相關的,如太早釋放等)。只要你保存了每一塊「內存管理」的數據,你怎麼訪問你的數據真的不重要。

我可以告訴你我是如何做這種數據管理的。

我通常命名爲DataManager

DataManager的。^ h

#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 
} 

我希望你有這個想法...也許你張貼一些代碼片段,所以我們可以查找與您的單身;-)

腳麻

更新:好的,所以你添加了代碼片段,問題很明顯在這一行:

[[DataLoader sharedDataLoader] setVeHint:results]; 

要設置veHint是results,所以你將要覆蓋的DataLoader的私有變量。你不應該這樣做,因爲results被釋放,DataLoader會失去參考。

您應該再寫setter方法,這使得results副本,並把該元素veHint

保留results它傳遞給的DataLoader這樣後:

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

但是,此解決方案(以及您的解決方案)會產生內存泄漏,因爲您在DataLoader中保留了veHint,並將其覆蓋在您的代理中(您的代表letely失去了參考veHint)。

+0

在單而言,通過給定septi樣品上方是相當多我對單的DataLoader類的代碼,除我的NSMutableArray和方法的變量以返回一個NSMutableArray內的特定值。 – prazzledazzle 2012-01-17 22:55:07

+0

我認爲問題是**你如何返回**並管理你傳遞的對象。你真的應該上傳一些代碼;-) – tamasgal 2012-01-17 23:42:38

+0

代碼片段添加爲請求 - 抱歉延遲。 – prazzledazzle 2012-01-23 19:48:43

0

默認情況下,核心數據不是線程安全的。如果您嘗試在多個線程中使用它,請確保您熟悉Apple's guidelines

+0

謝謝。我不介意Core Data不是單身人士。實際上,我只是使用bog標準方法從App Delegate類訪問sqlite數據庫。我只想使用從數據庫獲取的結果並在單例類中設置變量,以便我的主遊戲場景可以訪問過濾的數據。如果這是有道理的。 – prazzledazzle 2012-01-17 23:00:56

相關問題