3

我有一个应用程序可以从解析中下载并显示大量图像。几乎每分钟都会将图像添加到数据库中。由于 PFFile 是自动缓存的,没有过期日期,即使我只需要显示最近的图像,旧的图像仍然保留在缓存中,因此占用了大量的存储空间。因此,现在该应用程序在我的 iPhone 上占用了大约 5GB 的存储空间。我一直在对这个问题进行大量研究,发现 Parse 没有用于清理 PFFile Cache 的公共 api,并且它也不允许在缓存文件上设置过期日期。是否有解决方法,我可以手动删除较旧的缓存数据?

先感谢您。

4

4 回答 4

10

这是一种可用于清理 PFFile 缓存的方法。如果您在应用程序启动时调用它,在初始化 Parse 之前,我认为它应该是安全的。如果您不想删除所有内容,可以在 for 循环中检查文件创建日期。

+ (void)cleanUpPFFileCacheDirectory
{
    NSError *error = nil;
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSURL *cacheDirectoryURL = [[fileManager URLsForDirectory:NSCachesDirectory inDomains:NSUserDomainMask] lastObject];
    NSURL *PFFileCacheDirectoryURL = [cacheDirectoryURL URLByAppendingPathComponent:@"Parse/PFFileCache" isDirectory:YES];
    NSArray *PFFileCacheDirectory = [fileManager contentsOfDirectoryAtURL:PFFileCacheDirectoryURL includingPropertiesForKeys:nil options:0 error:&error];

    if (!PFFileCacheDirectory || error) {
        if (error && error.code != NSFileReadNoSuchFileError) {
            NSLog(@"Error : Retrieving content of directory at URL %@ failed with error : %@", PFFileCacheDirectoryURL, error);
        }
        return;
    }

    for (NSURL *fileURL in PFFileCacheDirectory) {
        BOOL success = [fileManager removeItemAtURL:fileURL error:&error];
        if (!success || error) {
            NSLog(@"Error : Removing item at URL %@ failed with error : %@", fileURL, error);
            error = nil;
        }
    }
}
于 2014-11-06T19:29:18.653 回答
4

TimWhiting 的答案翻译为 Swift 2.1:

注意:我不得不说,正如马特 S 所说,我认为最好使用文件 url 并使用您自己的缓存系统,我只是出于测试目的使用它。我还希望 Parse 可以为我们提供正确的路径,而不必对其进行硬编码,这就是我认为使用 URL 更好的原因。

func cleanUpParseDirectory(){
    let parseFilesCache = "Parse/PFFileCache"
    let fileManager = NSFileManager.defaultManager()
    let cacheDirectoryURL  = fileManager.URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask)
    let PFFileCacheDirectoryURL = cacheDirectoryURL[0].URLByAppendingPathComponent(parseFilesCache, isDirectory: true)
    do {
        let PFFileCacheDirectory = try fileManager.contentsOfDirectoryAtURL(PFFileCacheDirectoryURL, includingPropertiesForKeys: nil, options: [])
        print("number of cached files: \(PFFileCacheDirectory.count)")
        for fileURL in PFFileCacheDirectory {
            try fileManager.removeItemAtURL(fileURL)
        }
        print("Success removing items")
    } catch let error {
        print("Error: \(error)")
    }
}
于 2015-11-16T11:00:09.427 回答
1

根据 Hector 的回答:https : //www.parse.com/questions/pffile-cache-size 如果您坚持,您可以手动清除应用程序 ~/Library/Caches 文件夹。但是,我相当肯定这也会影响 NSURL/AFNetworking 缓存等内容。

我的建议?不要使用 PFFile 下载文件。PFFile 将远程 URL 返回到它在 Parse 站点上托管的位置,因此您可以将其传递给 AFNetworking 或 NSURLSession 之类的东西以实际为您下载图像,然后您可以分配缓存生命周期(或自己管理),因为那些与 PFFile 不同,系统实际上支持这一点。

于 2014-11-05T21:57:49.167 回答
1

deadbeef 的答案为任何需要它的人翻译成 Swift。

func cleanUpParseDirectory(){

    var error: NSError?

    var fileManager: NSFileManager = NSFileManager.defaultManager()

    var cacheDirectoryURL: [NSURL] = fileManager.URLsForDirectory(NSSearchPathDirectory.CachesDirectory, inDomains: NSSearchPathDomainMask.UserDomainMask) as! [NSURL]

    var PFFileCacheDirectoryURL: NSURL = cacheDirectoryURL[0].URLByAppendingPathComponent("Parse/PFFileCache", isDirectory: true)

    var PFFileCacheDirectory: [AnyObject]? = fileManager.contentsOfDirectoryAtURL(PFFileCacheDirectoryURL, includingPropertiesForKeys: nil, options: NSDirectoryEnumerationOptions.allZeros, error: &error)// [fileManager contentsOfDirectoryAtURL:PFFileCacheDirectoryURL includingPropertiesForKeys:nil options:0 error:&error];

    if (PFFileCacheDirectory == nil || error != nil) {
        if ((error != NSFileReadNoSuchFileError && error!.code != NSFileReadNoSuchFileError)) {
            println("error finding path")
        } else {
            println("no error finding path")
        }
        return
    }

    println("number of cached files: \(PFFileCacheDirectory!.count)")

    for fileURL in PFFileCacheDirectory! {


        var success: Bool = fileManager.removeItemAtURL(fileURL as! NSURL, error: &error)

        if ((!success != false || error != nil) ) {

            println("error removing item")

            error = nil

        } else {
            println("success removing item")
        }
    }
}
于 2015-08-10T23:32:11.590 回答