解压缩而不会增加内存

时间:2014-03-11 13:36:45

标签: ios objective-c memory memory-management

我有功能,执行解压缩过程。输入是从服务器下载的zip文件(NSData*类型)。解压缩的方法:

  1. 将数据临时存储在文件系统中。 (data - > filePath)
  2. 使用第三方解压缩库解压缩(Objective-zip)(filePath - > NSDictionary)
  3. 这很好用,除了一件事:使用ARC内存重复! zipData与来自磁盘的数据同时在内存中! 如果是大文件(例如大于100 Mb),则会导致严重的内存问题!

    如何强制ARC在将zipData写入磁盘后释放它? 只有当我要为两个不同的代码片分开这个函数时才有可能(比如之前描述的两个步骤)?

    以下是代码:

    - (NSDictionary*) zipContentOfData:(NSData*)zipData{
        NSString* tmpPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 
                                                      NSUserDomainMask,
                                                      YES) lastObject];
        NSString* randomZipFileName = @"tmpzip.zip";
        NSString* filePath = [tmpPath stringByAppendingPathComponent:randomZipFileName];
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL res = [fileManager createFileAtPath:filePath contents:nil attributes:nil];
        res = [zipData writeToFile:filePath atomically:NO];
    
        //I would like to release zipData here!
        NSDictionary *zipContent= nil;
        @try {
            //try to zip out!
            zipContent = [MCZippingHelper unZipFile:filePath];
        }
        @catch (ZipException *ze) {
            //a zipping error!
            //return nil;
        }
        @finally {
            [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
        }
    
        return zipContent;
    }
    

1 个答案:

答案 0 :(得分:0)

我在同一个线程上使用了几个嵌入式dispatch_asych来处理它(所以我使用completionBlock使它异步)。

- (void) zipContentOfData:(NSData*)zipData withCompletion:(void (^)(NSDictionary*, NSError*))completion{
NSString* tmpPath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, 
                                              NSUserDomainMask,
                                              YES) lastObject];
NSString* randomZipFileName = @"tmpzip.zip";
NSString* filePath = [tmpPath stringByAppendingPathComponent:randomZipFileName];
NSFileManager *fileManager = [NSFileManager defaultManager];
BOOL res = [fileManager createFileAtPath:filePath contents:nil attributes:nil];
res = [zipData writeToFile:filePath atomically:NO];


//I would like to release zipData here!
dispatch_async(dispatch_get_main_queue(), ^{
   NSDictionary *zipContent= nil;
   @try {
       //try to zip out!
       zipContent = [MCZippingHelper unZipFile:filePath];
       if(completion)completion(zipContent,nil);
   }
   @catch (ZipException *ze) {
    //handle zipping error on some way!
   }
   @finally {
       [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
       if(completion) completion(nil, [NSError errorWithDomain:@"zippingException" code:-200 userInfo:nil]);
   }

});
}

祝你好运!