1

使用 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 的原因。

任何建议,将不胜感激。

4

1 回答 1

-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 的弱变量并使用它来打破循环。

如果这些不起作用 - 运行仪器并记下哪些对象保留在内存中以及它们的引用计数何时更改。

于 2013-10-10T11:05:17.660 回答