【问题标题】:Does NSFileWrapper load everything into memory?NSFileWrapper 是否将所有内容加载到内存中?
【发布时间】:2012-11-17 06:34:28
【问题描述】:

假设我有一个NSFileWrapper 目录。该目录由多级目录和文件组成。有些文件很大。是所有这些文件都加载到内存中,还是延迟加载?

如果它们被加载到内存中,是否有任何替代 NSFileWrapper 的替代品具有类似的功能,不会将文件加载到内存中?我可以连接到UIDocument 的东西吗?


这是一个基于文档的应用程序,它使用与 iCloud 同步的UIDocument。文档中可以嵌入图像和视频。每个图像/视频都有一个显示在 HTML 文档中的预览图像(缩略图)。不应将完整尺寸的图像或视频加载到内存中,而应按需加载。

我还需要一种方法来添加资源而不将其加载到内存中。像“initWithAsset:(ALAsset *)”这样的东西是理想的。

【问题讨论】:

    标签: ios uidocument nsfilewrapper


    【解决方案1】:

    我不久前制作了一个可以生成视频的应用。然后使用 UIDocument 子类将该视频保存为特定的文件格式。

    在执行contentsForType:error: 时使应用程序不会耗尽内存的唯一方法是将视频输出到 tmp 目录中的一个文件,并使用NSFileWrapperReadingWithoutMapping 选项以防止它从将视频加载到内存并复制到文件中。

    - (id)contentsForType:(NSString *)typeName error:(NSError **)outError {
        if (self.fileWrapper == nil) {
            self.fileWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
        }
    
            if (self.videoURL != nil) {
    
                NSError *fileReadError;
                NSFileWrapper *videoFileWrapper = [[NSFileWrapper alloc] initWithURL:self.videoURL options:NSFileWrapperReadingWithoutMapping error:&fileReadError];
    
                if(fileReadError){
                    NSLog(@"File read error: %@", [fileReadError localizedDescription]);
                }else {
                    [videoFileWrapper setPreferredFilename:@"video.mov"];
                    [self.fileWrapper addFileWrapper:videoFileWrapper];
                }        
    
            }
    //...
    }
    

    【讨论】:

    • 嗨,JoriDor,我遇到了与您完全相同的问题;将视频存储在 NSFileWrapper 中。我已经使用initWithURL:options:error: 方法尝试了您的 tmp 解决方案,但在contentsForType:error: 返回后 RAM 使用率仍然很高。你找到解决方案了吗?
    • 嗨,Rengers,如果上述方法没有帮助,您可以从捆绑定义中排除视频。当我的班级编写包时,我将文件复制到包中。阅读时,我只是在包中搜索一个视频文件并使用 NSURL 指向它。
    • Tnx JoriDor。虽然感觉有点像 hack,但看起来它可以解决问题。
    • Rangers,有一种方法可以干净利落地执行此操作,具体取决于您有多少时间,那就是创建您的自定义 FileWrapper。互联网上有几个,其中之一是 Luke Scott 的 LSWrapper。见github.com/lukescott/LSFileWrapper
    【解决方案2】:

    从文档中并不完全清楚,但我 99% 的肯定NSFileWrapper 将记忆映射一切NSFileWrapper 的主要用例是将文件嵌入到文档中,您可能需要随时访问该文件。

    您想使用文件包装器做什么?我假设如果您要映射整个目录,则不一定要将媒体嵌入文档中,但也许我弄错了。如果您可以多谈谈您的用例,因为这会影响您可能选择的替代方案。

    【讨论】:

    • 我最终编写了自己的包装类,它不会将任何内容加载到内存中。我重载了UIDocument 中的writeContents:andAttributes:safelyToURL:forSaveOperation:error:readFromURL:error: 方法,以添加对我的自定义对象的支持。
    • @Luke 我相信存在混淆。内存映射文件实际上确实意味着延迟加载,并通过页面进入活动内存。另外,如果你保留一个指向原始目录 tupe NSFileWrapper 的指针,它将执行增量保存。
    • 2020年还是一样吗?
    猜你喜欢
    • 2021-04-14
    • 1970-01-01
    • 2018-11-21
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    相关资源
    最近更新 更多