2013-10-10 5 views
1

AFNetworking을 사용하여 서버에서 파일을 다운로드하십시오. 코드는 다음과 같습니다.AFNetworking 메모리

self.networkQueue = [[[NSOperationQueue alloc] init] autorelease]; 
[networkQueue setMaxConcurrentOperationCount:3]; 

for(NSDictionary* fileDictionary in self.syncArray) { 
    @autoreleasepool { 

     if([[fileDictionary allKeys] containsObject:@"downloadZipURL"]) { 
      NSString* downloadPath = [fileDictionary objectForKey:@"downloadZipURL"]; 
      downloadPath = [downloadPath stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]; 
      NSURLRequest *requestURL = [NSURLRequest requestWithURL:[NSURL URLWithString:downloadPath]]; 

      NSString* localDestPath = [NSString stringWithFormat:@"%@/%@", [FileUtil userDocumentsDirectory], [downloadPath lastPathComponent]]; 
      NSString* localTempPath = [NSString stringWithFormat:@"%@.tmp", localDestPath]; 
      [(NSMutableDictionary*)fileDictionary setObject:localDestPath forKey:@"downloadDestination"]; 

      AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:requestURL]; 
      operation.outputStream = [NSOutputStream outputStreamToFileAtPath:localDestPath append:NO]; 
      operation.userInfo = fileDictionary; 

      [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
       if (networkQueue.operationCount == 0) 
       { 
        if(hasDownloadError || isCancellingSync) { 
         return ; 
        } 

        [self performSelectorInBackground:@selector(processAllFiles) withObject:nil]; 

       } 

      } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
       NSLog(@"Error: %@", error); 
      }]; 

      //   [operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { 
      //    NSLog(@"Sent %lld of %lld bytes, %@", totalBytesWritten, totalBytesExpectedToWrite, localDestPath); 
      //    float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite; 
      //    [(NSMutableDictionary*)operation.userInfo setObject:[NSString stringWithFormat:@"Downloading %.0f%%", progress*100] forKey:@"downloadStatus"]; 
      //    [(NSMutableDictionary*)operation.userInfo setObject:[NSNumber numberWithFloat:progress] forKey:@"downloadProgress"]; 
      //    [syncViewController onPermitUpdated]; 
      //   }]; 

      [networkQueue addOperation:operation]; 
     } 
    } 
} 

일단이 코드가 실행되면 메모리가 천천히 먹히고 결코 되돌려지지 않습니다. 자, 이것들은 큰 파일 일 수 있습니다. 그래서 나는 outputStream을 사용했습니다.

의견을 보내 주시면 감사하겠습니다.

답변

-1

내 머리 꼭대기에서 벗어남 - ARC를 사용하고 있지 않은 것으로 나타났습니다.

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:requestURL]

어딘가에이 작업을 해제하고 있습니까? 여기

[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
       if (networkQueue.operationCount == 0) 
       { 
        if(hasDownloadError || isCancellingSync) { 
         return ; 
        } 

        [self performSelectorInBackground:@selector(processAllFiles) withObject:nil]; 

       } 

, 당신은 completionBlock에 networkQueue을 사용하고 있고 블록이 networkQueue을 유지, 당신은 그들 중 어느 것도 할당 해제에 이르게 동작을 유지 networkQueue에 작업을 추가합니다. networkQueue의 약한 변수를 만들어서주기를 깨는 데 사용하십시오.

그래도 작동하지 않으면 악기를 실행하고 메모리에 남아있는 개체 및 참조 횟수가 변경된 경우 메모하십시오.

+0

실례합니다. 첫째로, ARC가 전부 아니면 아무것도 아닌 제안입니까? 나는 그것을 networkQueue에서 사용할 수 없다. networkQueue에서 자동 해제가 핸들 할당 해제를 처리하지 않습니까? 거대한 파일을 다운로드하는 중에도 메모리 증가 문제는 해결되지 않습니다. – David

+0

네, 전부 또는 아무것도 아니므로 networkQueue에 사용할 수 없습니다. 예, autorelease가 networkQueue를 출시하지만 작동 자체는 해제되지 않습니다. 그렇게해야합니다. 그걸 처리 했니? 작업을 공개하지 않으면 해당 데이터 중 일부가 유지 될 수 있습니다. 구현이 무엇인지 확실하지 않습니다. – Andrew

+0

코드를 너무 많이 보았을 것입니다. 나는 풀려나지 않은 작전을 놓쳤다. 나는 또한 그것에 autorelease를 뒀다. 다운로드가 완료된 후에도 메모리는 여전히 사용됩니다. – David