2017-06-15 10 views
0

データがNSArrayにダウンロードされると、オフラインですべてのアイテムをローカルに保持する必要があるため、NSArrayに多数のアイテムをダウンロードしていますNSURLSession競合ハンドラでは、私のアプリのメモリ使用量は約120 MBとかなり控えめですが、このNSArrayをループしてコアデータにデータを挿入し、メモリスパイクを2 GBまで高速に保存してからメモリの問題によりアプリケーションが終了します。 NSArrayを配列のNSArrayに分割して、各バッチがディスクに保存された後にメモリを解放しようとしましたが、これが役に立たないので何かが欠けているはずです。私は間違って何をしていますか?私は、データをローカルに持っている必要がありますので、私はオフラインのシナリオを提供する必要があるので、ダウンロードしたデータを取得することができるメモリ足のプリントを低く保つ必要があります。短い多くのデータをコアデータに保存すると、メモリの問題によりアプリケーションが終了する

メモリ使用量で

完了ハンドラは、forループを開始し、急速に、約120メガバイト それをある2ギガバイトに増加し、アプリは、Appが

が、私は以下のコードを添付していますフォアグラウンドで常に を終了しますダウンロードして保存したデータ

+ (void)fetchTillDataAll:(int)tillId :(int)startAtRow :(int)takeNoOfRows { 

    if ([NWTillHelper isDebug] == 1) { 
     NSLog(@"WebServices:fetchTillDataAll:tillId = %d, startAtRow = %d, takeNoOfRows = %d", tillId, startAtRow, takeNoOfRows); 
    } 

    NSString *finalURL = [NSString stringWithFormat:@"https://host.domain.com/api/foo/bar]; 

    [[[NSURLSession sharedSession] dataTaskWithURL:[NSURL URLWithString:finalURL] 
           completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 

            if (error != nil) { 
             if ([NWTillHelper isDebug] == 1) { 
              NSLog(@"WebServices:fetchTillDataAll:Transport error %@", error); 
             } 
            } else { 
             NSHTTPURLResponse *responseHTTP; 
             responseHTTP = (NSHTTPURLResponse *) response; 

             if(responseHTTP.statusCode != 200) { 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchTillDataAll:Server Error %d", (int) responseHTTP.statusCode); 
              } 
             } else { 
              NSArray *tillBasicDataArray = [NSJSONSerialization JSONObjectWithData:data 
                              options:0 
                              error:NULL]; 
              if ([NWTillHelper isDebug] == 1) { 
               NSLog(@"WebServices:fetchTillDataAll:tillBasicDataArray count = %lu", (unsigned long)[tillBasicDataArray count]); 
               NSLog(@"WebServices:fetchTillDataAll:tillBasicDataArray looks like %@",tillBasicDataArray); 
              } 

              AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication]delegate]; 


              NSPersistentContainer *container = appDelegate.persistentContainer; 

              NSArray *arrayOfArrays = [NWTillHelper splitIntoArraysOfBatchSize:tillBasicDataArray :1000]; 

              for(NSArray *batch in arrayOfArrays) { 

               [container performBackgroundTask:^(NSManagedObjectContext *context) { 
                context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy; 

                NSDictionary *tillBasicDataDict = Nil; 

                / 
                / 
                for (id element in batch){ 
                 tillBasicDataDict = element; 

                 NSString *itemId = [tillBasicDataDict objectForKey:@"itemId"]; 
                 NSString *brandId = [tillBasicDataDict objectForKey:@"companyId"]; 
                 NSString *languageId = [tillBasicDataDict objectForKey:@"languageCode"]; 
                 NSString *colorCode = [NSString stringWithFormat:@"%@", [tillBasicDataDict objectForKey:@"colorCode"]]; 
                 NSString *discountable = [tillBasicDataDict objectForKey:@"discountable"]; 
                 NSString *exchangeable = [tillBasicDataDict objectForKey:@"exchangeable"]; 
                 NSString *noos14 = [tillBasicDataDict objectForKey:@"noos14"]; 
                 NSString *sizeCode = [NSString stringWithFormat:@"%@", [tillBasicDataDict objectForKey:@"sizeCode"]]; 
                 NSString *taxGroup = [tillBasicDataDict objectForKey:@"taxGroupId"]; 
                 NSString *taxRegion = [tillBasicDataDict objectForKey:@"taxRegion"]; 
                 NSString *tradeItemDesc = [tillBasicDataDict objectForKey:@"tradeItemDesc"]; 
                 NSString *withTax = [tillBasicDataDict objectForKey:@"withTax"]; 
                 NSString *status = [tillBasicDataDict objectForKey:@"status"]; 

                 / 


                 NSManagedObject *newPimItem = Nil; 
                 newPimItem = [NSEntityDescription 
                     insertNewObjectForEntityForName:@"TillData" 
                     inManagedObjectContext:context]; 

                 [newPimItem setValue:itemId forKey:@"itemId"]; 
                 [newPimItem setValue:brandId forKey:@"brandId"]; 
                 [newPimItem setValue:languageId forKey:@"languageCode"]; 
                 [newPimItem setValue:colorCode forKey:@"colorCode"]; 
                 [newPimItem setValue:discountable forKey:@"discountable"]; 
                 [newPimItem setValue:exchangeable forKey:@"exchangeable"]; 
                 [newPimItem setValue:noos14 forKey:@"noos14"]; 
                 [newPimItem setValue:sizeCode forKey:@"sizeCode"]; 
                 [newPimItem setValue:[NSNumber numberWithInt:[taxGroup intValue]] forKey:@"taxGroup"]; 
                 [newPimItem setValue:taxRegion forKey:@"taxRegion"]; 
                 [newPimItem setValue:tradeItemDesc forKey:@"tradeItemDesc"]; 
                 [newPimItem setValue:[NSNumber numberWithInt:[withTax intValue]] forKey:@"withTax"]; 
                 [newPimItem setValue:[NSNumber numberWithInt:[status intValue]] forKey:@"status"]; 

                 if ([NWTillHelper isDebug] == 1) { 
                  NSLog(@"WebServices:fetchTillDataAll:ItemId in loop = %@", itemId); 
                  NSLog(@"WebServices:fetchTillDataAll:newPimItem = %@", newPimItem); 
                  NSLog(@"WebServices:fetchTillDataAll:CoreData error = %@", error); 
                 } 

                } 
                NSError *error = nil; 
                if (![context save:&error]) { 
                 NSLog(@"Failure to save context: %@\n%@", [error localizedDescription], [error userInfo]); 
                 abort(); 
                } else { 
                 NSUserDefaults *tillUserDefaults = [NSUserDefaults standardUserDefaults]; 
                 [tillUserDefaults setInteger:1 forKey:@"hasTillData"]; 
                 [tillUserDefaults synchronize]; 
                } 
               }]; 
              } 
             } 
            } 
           }] resume]; 
} 

NSArrayの分割方法は次のように見えること

以下
+ (NSArray *) splitIntoArraysOfBatchSize:(NSArray *)originalArray :(int)batchSize { 

    NSMutableArray *arrayOfArrays = [NSMutableArray array]; 

    for(int j = 0; j < [originalArray count]; j += batchSize) { 

     NSArray *subarray = [originalArray subarrayWithRange:NSMakeRange(j, MIN(batchSize, [originalArray count] - j))]; 
     [arrayOfArrays addObject:subarray]; 
    } 

    return arrayOfArrays; 
} 

---- EDIT ----

私も1000年、レコードのバッチにダウンロードを分割しようとしたが、それはどちらか助けていません。

while (loopCount < numberOfLoops) { 
      if([NWTillHelper isDebug] == 1) { 
       NSLog(@"%s loopCount = %d", __PRETTY_FUNCTION__, loopCount); 
       NSLog(@"%s startAtRow = %d", __PRETTY_FUNCTION__, startAtRow); 
       NSLog(@"%s records to fetch = %@", __PRETTY_FUNCTION__, recordsToFetchStr); 
      } 

     //[self fetchPricelistAll:(int)[NWTillHelper getPricelist] :0 :recordsToFetch]; 
     [self fetchPricelistAll:(int)[NWTillHelper getPricelist] :startAtRow :batchSizeInt]; 

     startAtRow = startAtRow + batchSizeInt; 

     loopCount++; 
    } 
+0

私も@autoreleasepoolを使用してみました、それは状況 –

答えて

0

データをビット単位で分割することをお勧めします。あなたはサーバーからビットをダウンロードし、テキストファイルとしてドキュメントフォルダに保存することができます。テキストファイルからデータを順次取り込み、コアデータに保存します。コアデータへの保存が完了したらファイルを削除します。

+0

を改善していない私は、1000年、レコードのバッチでデータをロードを試みたが、まだ、問題は同じまま、方法がなければならない問題ではありません。各バッチが完了したらメモリを解放するために、バッチサイズの各ループの後にtxtファイルに保存するのは非常に醜いハッキングのように聞こえるのですが、なぜメモリが解放されないのですか? –

+0

同時に、すべてのデータをコアデータに同時に保存しています。一度に1つのバッチをコアデータに保存するとどうなりますか?それはメモリプリントを減らすでしょう。 – pkallu

+0

すでに各バッチの後に保存されています。各バッチには1000レコードが保存されています。すでにバックグラウンドブロックに保存されていますので、各バッチ後に保存することを意味していました。 –

0

我々は100/1000レコードを作成した後のメソッドの下にコンテキスト上の保存方法

  1. コールに従うことができます。
  2. 保存後、リセットメソッドをコンテキストと呼びます。

    [managedObjectContext reset];

関連する問題