2010-12-07 2 views
0

CoreDataにデータを追加しようとしています。私はXcodeから電話機をビルドするとうまく動作しますが、iPhoneから直接アプリを起動しようとすると、コンテキストに最初に保存するとクラッシュします。Core Dataに多数のプロパティを追加していますが、電話機からは起動してもXcodeからは起動しません。

iTunesのファイル共有で同期されるテキストファイルを読むと、ファイルがかなり大きくなります(〜350,000行)。ファイルから取得した値は、2つの異なる配列(バーコードとproductNames)に追加されます。配列は後でバッチ処理され、データを保存する関数に送られます。 [...]

 words = [rawText componentsSeparatedByString:@";"]; 

    int loopCounter = 0; 
    int loopLimit = 20000; 

    int n = 0; 
    int wordType; 
    NSEnumerator *word = [words objectEnumerator]; 
    NSLog(@"Create arrays"); 
    while(tmpWord = [word nextObject]) { 

     if ([tmpWord isEqualToString: @""] || [tmpWord isEqualToString: @"\r\n"]) { 
      //   NSLog(@"%@*** NOTHING *** ",tmpWord); 
     }else { 



      n++; 
      wordType = n%2; 

      if (wordType == kBarcode) { 
       [barcodes addObject: tmpWord]; 

      }else if (wordType == kProduct) { 
       [productNames addObject: tmpWord]; 
      } 
      // Send to batch // 
      loopCounter ++; 

      if (loopCounter == loopLimit) { 
       loopCounter = 0; 
       NSLog(@"adding new batch"); 
       [self addBatchOfData]; 

       [barcodes release]; 
       [productNames release]; 

       barcodes = [[NSMutableArray arrayWithCapacity:20000] retain]; 
       productNames = [[NSMutableArray arrayWithCapacity:20000] retain]; 


      } 

     } 

[...]

[保存機能:

-(void)addBatchOfData { 
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
NSError *error; 

NSUInteger loopLimit = 5000; 
NSUInteger loopCounter = 0; 

NSString *ean; 
NSString *designation; 

for (int i=0; i<[barcodes count];i++) { 

    ean = [barcodes objectAtIndex:i]; 
    designation = [productNames objectAtIndex:i]; 

    Product *product = (Product *)[NSEntityDescription insertNewObjectForEntityForName:@"Product" inManagedObjectContext:importContext]; 
    [product setDesignation:designation]; 
    [product setBarcode:ean]; 

    loopCounter ++; 
    if (loopCounter == loopLimit) { 
     NSLog(@"Save CoreData"); 
     [importContext save:&error]; 
     [importContext reset]; 
     [pool drain]; 

     pool = [[NSAutoreleasePool alloc] init]; 

     loopCounter = 0; 
    } 
} 
// Save any remaining records 
if (loopCounter != 0) { 
    [importContext save:&error]; 
    [importContext reset]; 
} 
[pool drain]; 

}アレイループから

Xcodeからビルドするとうまく動作するのは本当に面白いです。うまくいけば、私が逃した設定や何かがあります...

EDIT:私はデフォルト画面を通過しないと言及して忘れて、私はログを持っていません。プロビジョニングと関連がありますか?

答えて

0

バックグラウンドスレッドでファイルをロードしてオフにして、電話機がメインウィンドウとビューを起動できるようにします。タイムリーなマナーに表示しないと、iOSはアプリを強制終了します(これはあなたが見ているものです)。

私はxml - > CoreDataコンバータコードでこれを行う必要があります。私はちょうど起こっていることと進行状況バー(私はhttps://github.com/matej/MBProgressHUDを使用している)を通知するビューをユーザに提示します。 何かのように:

self.hud = [[MBProgressHUD alloc] initWithView:window]; 

// Set determinate mode 
hud.mode = MBProgressHUDModeDeterminate; 
hud.delegate = self; 
hud.labelText = @"Converting Data File"; 
[self.window addSubview:hud]; 

// Show the HUD while the provided method executes in a new thread 
[hud showWhileExecuting:@selector(convertToCoreDataStoreTask) onTarget:self withObject:nil animated:YES]; 

あなたはちょうどあなたが新しいスレッドで別々のNSManagedObjectContextを使用することを確認する必要があります。

+0

ブレントありがとう!それが実際に私がそれをどのように解決したかです。私は新しいスレッドを作るのがいかに簡単か驚いた。 – Mike

0

私は、このデリゲートメソッドを実装し、メモリで何が起こっているのかを調べることをお勧めします。

シミュレータで実行しているとき、あなたは何のメモリの制約を持っていませんが、携帯電話で動作しているときに、私は私の質問への解決策を見つける

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application 
{ 
} 
+0

ありがとう、私はシミュレータでそれを実行しないことですが、私はデバイスにそれを構築します。私がそれをすると、うまくいく... – Mike

0

思います。

私がやっていたことは、 " - (void)viewDidLoad {"}で大量のデータが壊れてしまったことでした。私がアプリ内のボタンをクリックした後にクランチを開始するように変更したところ、うまくいきました。

今はちょうどデータのクランチがどこから始まるのかを知るだけです。