0

6000 개 이상의 고해상도 (약 2.6GB)를 다운로드 중이지만 Google 고객 로그인에 따라 변경 될 수 있습니다. 판매 대리점은 해외에있을 때 모든 제품 이미지를로드해야하기 때문에 오프라인 모드에서 모두 사용할 수 있어야합니다.큰 이미지 다운로드 루프가 GCD 큐 내부에서 새어 나옴

내 코드는 매우 특별하며 코드 유출 문제는 경험이 많은 Objective-C 프로그래머에게는 매우 분명합니다.

현재 상태는 코드가 6253의 2041 및 580 초가 다운로드되었음을 나타냅니다. 그러나 에뮬레이터의 메모리는 이미 931MB입니다.

각 루프 또는 X- 루프 순환 후 메모리를 다시 얻으려면이 코드를 개선하기 위해 어떤 조치를 취할 수 있습니까?

int total_new_images = total_images_in_db - total_images_locally; 

// Fetch the real pictures now 
dispatch_queue_t imageQueue = dispatch_queue_create("Image Queue", DISPATCH_QUEUE_CONCURRENT); 

dispatch_async(imageQueue, ^{ 
    NSString *path = [NSString new]; 
    NSURL *url = [NSURL new]; 
    NSData *data = [NSData new]; 
    NSString *savePath = [NSString new]; 
    NSArray *imgUrlArray = [NSArray new]; 

    NSDate *starTime = [NSDate new]; 

    @autoreleasepool { 
     int c = 0; 

     FMResultSet *rs = [self.efashionDB executeQuery:@"SELECT * FROM app_images"]; 

     while ([rs next]) { 
      imgUrlArray = [[rs stringForColumn:@"full_url"] componentsSeparatedByString:@"/"]; 

      savePath = [NSString stringWithFormat:@"%@/%@", imgFolder, [imgUrlArray objectAtIndex:[imgUrlArray count]-1]]; 

      if ([self.fileMgr fileExistsAtPath:savePath]) { 
       //NSLog(@"'%@' is already saved locally.", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]); 
       continue; 
      } 

      path = [NSString stringWithString:[rs stringForColumn:@"full_url"]]; 
      url = [NSURL URLWithString:path]; 
      data = [NSData dataWithContentsOfURL:url]; 

      if (![data writeToFile:savePath atomically:YES]) { 
       NSLog(@"Saving of \"%@\" failed!", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]); 
      } else { 
       //NSLog(@"Saving of \"%@\" succeeded!", [imgUrlArray objectAtIndex:[imgUrlArray count]-1]); 

       // Escape back to the main thread and give status update 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        NSString *progress = [[NSString alloc] initWithFormat:@"%d of the %d new images downloaded\nTime passed: %d seconds", c, total_new_images, (int)([starTime timeIntervalSinceNow] * -1)]; 
        [_imageConsole setText:progress]; 
       }); 

       c++; // Only increment if it succeeded 
      } 

      if (c == 20) { 
       //break; 
      } 
     } 
     [rs close]; 
    } 
}); 

답변

2

while 루프 내부에서 @autoreleasepool을 이동해보십시오. 그렇지 않으면 할당 된 객체는 while 루프가 끝날 때까지 해제되지 않습니다.

+0

iljawascoding에 감사드립니다. 방금 앱을 프로파일 링했습니다. 누출 기록은 보이지 않습니다. * All Heap & Anonymous VM *, All Heap Allocations * 및 All Anonymouse VM * Bytes가 매우 빠르게 증가합니다. –

+1

while 루프 내부에서 @autoreleasepool을 이동해보십시오. 그렇지 않으면 할당 된 객체는 while 루프가 끝날 때까지 해제되지 않습니다. – iljawascoding

+0

LOL 너무 간단! Thumbnail 변종 (총 12.5k 파일)도 다운로드 중이며 메모리는 32MB 미만으로 유지됩니다. D. 훌륭한. 정말 고맙습니다! –

관련 문제