2013-10-10 33 views
1

使用AFNetworking從服務器下載文件。這裏的代碼:AFNetworking Memory

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]; 

       } 

在這裏,您使用的networkQueue在completionBlock和塊保留networkQueue,然後添加在操作中networkQueue,保留了操作,導致他們都沒有重新分配。嘗試製作networkQueue的弱變量並使用它來打破循環。

如果這些不起作用 - 運行儀器並記下哪些對象留在內存中以及何時更改其引用計數。

+0

請原諒我的無知。對象C中的Newb。首先,ARC不是一個全部或全部的命題?我不能只使用它在networkQueue上嗎?在網絡上不自動釋放隊列句柄釋放?仍然無法解決我正在下載大文件時增加內存的問題。 – David

+0

是的,這是全部或沒有,你不能只用它的networkQueue和是的,autorelease將釋放networkQueue,但它不會釋放操作本身,你應該這樣做。 你照顧過嗎?如果你不發佈操作,它可能會保留一些數據 - 我不確定它的實現是什麼。 – Andrew

+0

只是看着代碼太多我猜。我錯過了未被釋放的手術。我也放了autorelease。即使下載完成,內存仍然被佔用。 – David