2011-02-08 4 views
1

큰 데이터 세트 (~ 6,000)를 핵심 데이터 응용 프로그램으로 가져 오려고합니다. Apple 문서 "효율적으로 데이터 가져 오기"를 읽었으며 제대로 설정했다고 생각합니다. 이상한 일은 시뮬레이터에서 응용 프로그램이 충돌하지 않는 것입니다. 누출 도구로 실행해도 문제가되지 않지만 모든 데이터가 저장되지는 ​​않습니다. 때로는 3 ~ 4 백 번을 절약 할 수 있으며, 3 ~ 4 천 건이 저장되며 전체 데이터 세트는 거의 저장되지 않습니다. 나는 아마도 메모리 누수와 관련이 있다고 생각하고 NSAutoReleasePool을 사용하는 것에 대해 매우 익숙하다.핵심 데이터 가져 오기 실패

NSURL *url = [NSURL URLWithString:@""]; 

    NSString *responseString = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:nil]; 

    if (responseString) { 
     NSArray *players = [responseString componentsSeparatedByString:@";"]; 

     NSUInteger LOOP_LIMIT = 100, count = 0; 

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

     NSManagedObjectContext *context = [[AppController sharedAppController] managedObjectContext]; 
     [context setUndoManager:nil]; 

     for (int i=0; i<([players count] - 1); i++) { 
      NSArray *info = [[players objectAtIndex:i] componentsSeparatedByString:@","]; 

      NSString *dateInfo = [info objectAtIndex:10]; 
      NSLocale *usLocale = [[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]; 
      NSDateFormatter *fo = [[[NSDateFormatter alloc] init] autorelease]; 
      [fo setDateFormat:@"MM/dd/yyyy"]; 
      [fo setLocale:usLocale]; 
      [fo setTimeZone:[NSTimeZone systemTimeZone]]; 
      NSDate *dob = [fo dateFromString:dateInfo]; 

      Players *player = [NSEntityDescription insertNewObjectForEntityForName:@"Players" 
                  inManagedObjectContext:context]; 

      NSNumberFormatter *f = [[[NSNumberFormatter alloc] init] autorelease]; 
      [f setNumberStyle:NSNumberFormatterNoStyle]; 

      player.playerID = [f numberFromString:[info objectAtIndex:0]];    
      player.lastName = [info objectAtIndex:1]; 
      player.firstName = [info objectAtIndex:2]; 
      player.position = [info objectAtIndex:4]; 

      NSString *teamName = [info objectAtIndex:3]; 

      NSFetchRequest *req = [[[NSFetchRequest alloc] init] autorelease]; 

      NSEntityDescription *ent = [NSEntityDescription entityForName:@"Teams" inManagedObjectContext:context]; 
      [req setEntity:ent]; 
      [req setIncludesPropertyValues:NO]; 

      NSPredicate *pre = [NSPredicate predicateWithFormat:@"team=%@", teamName]; 
      [req setPredicate:pre]; 

      NSArray *list = [context executeFetchRequest:req error:nil]; 

      if ([list count]) { 
       Teams *team = [list objectAtIndex:0]; 

       player.team_Players_Teams = team; 
      } 

      count++; 

      if (count == LOOP_LIMIT) { 
       [context save:nil]; 

       [context reset]; 

       [pool drain]; 

       pool = [[NSAutoreleasePool alloc] init]; 

       count = 0; 
      } 
     } 

     if (count != 0) { 
      NSLog(@"In Save Remaining"); 

      [context save:nil]; 

      [context reset];[pool drain]; 
     } 
내가 어떤 명백한 누수 만 볼 수
+1

끝에 [풀 배수구]가 누락되었습니다. – Felix

+0

True - 방금 추가했으나 실제 가져 오기에는 영향을 미치지 않습니다. 아직 가져 오기 과정에서 약간의 오류가 있어야합니다. – nlutterman

답변

0

코드에서 아무 것도 볼 수 없습니다. 확실히 로그에 오류가 나타나지 않습니까?

Btw 데이터를 가져 오기위한 핵심 데이터 pdf에서 다루는 다른 최적화 팁은 루프 외부에서 조건 생성을 이동하고 대체 변수를 사용하는 것입니다.

+0

Nope가 오류를 내지 못했습니다. 마침내 LOOP_LIMIT을 10000으로 올려서 일종의 작업을 마쳤습니다. 이제 시뮬레이터와 장치에서는 항상 작동하지만 계측기에서는 작동하지 않습니다. 다행히도 이것은 응용 프로그램의 초기 시작에서만 수행되므로 문제가 될 것이라고 생각하지 않습니다. – nlutterman

+0

위의 편집이 10,000이 아니라 1,000으로 변경되었습니다. – nlutterman

0

:

  1. 당신은 -ing alloc init retain에서 사용하는 메모리의 양을 최소화 할 수를 NSLocale, NSDateFormatter, NSNumberFormatter 다음 release 애프터을 -ing 루프가 완료되었습니다. 루프 실행 사이에는 변경되지 않는 것으로 보입니다.

  2. 핵심 데이터는 모르지만 NSManagedObject/Player *player 개체는 어디에서 출시 되나요? 코어 데이터를 통해 자동 실행됩니까? 목록 응답에 따라

업데이트 전무 경우

여담으로
  • , 당신은 충돌합니다 마지막 두로 [list lastObject]보다는 [list count][list objectAtIndex:0]를 사용할 수 있습니다 아무것도가 수 있도록 표시되지 않으면

    차이가 있다면 다음 단계는 코드를 단순화하여 오류 소스를 제거하는 것입니다.

    1. 위의 # 1에서 제안 사항을 수행하여 루프의 코드 양을 최소화하십시오.

    2. list 개체를 어딘가에서 풀어 주는지 확인하거나 autorelease로 할당되어 있는지 확인하십시오.

    3. 중간 저장 (count == LOOP_LIMIT 안에있는 모든 코드)을 제거하고 모든 배열이 처리 된 후에 만 ​​저장 및 드레인하십시오. 또한 내부 코드가 필요하지 않아야합니다. if (count != 0)

    4. error:&&error 문을 로그 오류로 바꿉니다.오류는 다음과 같이 기록하지합니다 (사과를하지만, 코드 서식 작동하지 않는 것 - 아무 생각 왜) : NSError *error = nil; //Declared upfront

      // Your streamlined code

      // ....

      error = nil; //Just before a fetchRequest or context:save

      /* After looping through all your code now attempt to save */

      if(![context save:&error]) {

      NSLog(@"Failed to save to data store: %@", [error localizedDescription]); 
      NSArray *detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey]; 
      if(detailedErrors != nil && [detailedErrors count] > 0) { 
          for(NSError *detailedError in detailedErrors) { 
           NSLog(@"DetailedError: %@", [detailedError userInfo]); 
          } 
      } else { 
          NSLog(@" %@", [error userInfo]); 
      } 
      

      }

    5. 그런 다음 당신이 어떤 이상한 메시지를 얻고 있는지 확인하기 위해 로그를 확인하십시오. 또한 코어 데이터의 모든 부분에서 유사한 코드를 사용하여 오류를 확인해야합니다 (예 : executeFetchRequest). 오류가 무엇인지 알아낼 가치가 있습니다.

  • +0

    NSManagedObject Player는 내가 믿는 풀과 함께 출시되어야합니다. 불행히도 그것은 여전히 ​​부서지기 때문에 나는 그 이유를 모른다. – nlutterman

    +0

    더 많은 옵션과 의견으로 원래 응답을 업데이트했습니다. 이전 글은 코드를 읽을 수 없을만큼 작아서 제거했습니다. –

    관련 문제