iOS 缓存的清除及优化

作者: 逍遥晨旭 | 来源:发表于2017-03-20 14:37 被阅读448次

    缓存默认存储在cache中,APPStore中有一条明确规定,你的APP中缓存文件只能保存在沙盒路径下Caches文件夹或Temp文件夹下,不然将会被拒。而Temp文件夹下内容将会在APP退出时自动清除,所以我们清除APP缓存主要是清除Caches文件夹下的内容。而缓存文件包括两部分,一部分是使用SDWebImage缓存的内容,其次可能存在自定义的文件夹中的内容(视频,音频等内容),所以计算要分两部分。

    清除缓存一般做法是:1、计算缓存文件的大小;2、显示大小;3、弹框询问是否清除。

    1、计算缓存量(简单粗暴的计算法)

    - (double)getCacheSize {
    SDImageCache *imageCache = [SDImageCache  sharedImageCache];
     NSUInteger fileSize = [imageCache getSize]; // 以字节为单位
     NSString *myCachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject];
     NSFileManager *fileM = [NSFileManager defaultManager];
     NSDictionary *fileInfo = [fm fileM attributesOfItemAtPath:myCachePath error:nil];
    fileSize += fileInfo.fileSize;
     return fileSize/1024.0/1024.0;
    }
    

    把缓存量显示出来

    self.CacheLabel.text = [NSString stringWithFormat:@"%.2fM", [self  getCacheSize]];
    

    清除缓存的方法(直接调用,同样简单粗暴):

    //异步清除图片缓存 (磁盘中的)
    [[SDImageCache sharedImageCache] clearDisk];
    [[NSFileManager defaultManager] removeItemAtPath:[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject]error:nil];
    

    至此清除缓存功能是不是已经完成。如果不考虑性能问题那就已经完成了。而下面这两个方法:

     unsigned long long size = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).lastObject stringByAppendingPathComponent:@"CustomFile"].fileSize;
    size += [SDImageCache sharedImageCache].getSize; 
    

    /上述两个方法都是在主线程中完成的,如果缓存文件非常大的话,计算时间会比较长,会导致应用卡死,因此需要将上述代码放到子线程中完成。/

    正确的清除姿势

    [[SDImageCache sharedImageCache] clearDiskOnCompletion:^{
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [[SDImageCache sharedImageCache] clearDisk];
            [[NSFileManager defaultManager] removeItemAtPath:[NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask, YES)lastObject]error:nil];
            dispatch_async(dispatch_get_main_queue(), ^{
                // 设置文字
               self.CacheLabel.text = [NSString stringWithFormat:@"计算缓存大小0.0M";    
            });   
        });
    }];
    

    注意点:

    1、SDWebImage清除缓存是在子线程中进行的,清除自定义文件内容应该也放在子线程中(删除大文件可能比较耗时),为了保证两者不冲突,可以将删除自定义文件内容放在SDWebImage缓存清除完毕之后进行,然后再回到主线程操作。
    2、在计算文件大小过程中不允许点击清除按钮的
    3、缓存文件可能比较大,清除缓慢,可以给你清除动画(比如放一个菊花转圈圈)。

    更加人性化的是根据其大小再判断是否清除缓存。

    1、根据其大小再判断是否清除缓存。
    /**
    * 根据传过来的路径计算文件夹里内容或文件的大小
    *
    * @param filePath 文件夹或文件的路径
    *
    * @return 大小
    */
    - (NSUInteger)calculateFileSize:(NSString *)filePath
    {
    NSFileManager *fileManager = [NSFileManager defaultManager];

        //是否为文件
        BOOL isFile = NO;
        
        //判断文件或文件夹是否存在(也就是判断filePath是否是一个正确的路径)
        BOOL isExist = [fileManager fileExistsAtPath:filePath isDirectory:&isFile];
        
        if(!isExist) return 0;//不存在返回0
        
        if(!isFile)//是文件
        {
            return [[fileManager attributesOfItemAtPath:filePath error:nil][NSFileSize] integerValue];
        }
        else //是文件夹
        {
            //遍历文件夹中的所有内容
            NSArray *subPaths = [fileManager subpathsAtPath:filePath];
            NSUInteger totalBytes = 0;
            for(NSString *subPath in subPaths)
            {
                //NSLog(@"文件夹下的全部内容的路径:%@", subPath);
                //获取全路径
                NSString *fullPath = [filePath stringByAppendingString:[NSString stringWithFormat:@"/%@", subPath]];
                BOOL dir= NO;
                [fileManager fileExistsAtPath:fullPath isDirectory:&dir];
                
                if(!dir)//是文件就计算大小,注意文件夹是没有大小的所以就不用计算了
                {
                    totalBytes += [[fileManager attributesOfItemAtPath:fullPath error:nil][NSFileSize] integerValue];
                }
            }
            return totalBytes/1024.0/1024.0;
        }
    }
    

    2、根据路径删除文件或文件夹

    [[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
    

    只是总结自己的代码,方便以后看而已。也希望对读者有些许的帮助。

    相关文章

      网友评论

        本文标题:iOS 缓存的清除及优化

        本文链接:https://www.haomeiwen.com/subject/ykbbnttx.html