我可以创建一个引用内存中 NSData 的 NSURL 吗?

Posted

技术标签:

【中文标题】我可以创建一个引用内存中 NSData 的 NSURL 吗?【英文标题】:Can I create an NSURL that refers to in-memory NSData? 【发布时间】:2014-07-01 21:23:12 【问题描述】:

The docs for NSURL 声明:

一个 NSURL 对象代表一个可能包含 远程服务器上资源的位置,本地文件的路径 磁盘,甚至是任意一段编码数据

我有一个内存数据块,我想将其交给一个库,该库希望通过 NSURL 加载资源。当然,我可以先将此 NSData 写入临时文件,然后从中创建一个 file:// NSURL,但我更希望 URL 直接指向我已经存在于内存中的缓冲区。

上面引用的文档似乎表明这是可能的,但我找不到任何关于如何完成它的提示。我错过了什么吗?

【问题讨论】:

也许这意味着你可以给它一个数据URI? en.wikipedia.org/wiki/Data_URI_scheme 如果我有一个类似 -chart.googleapis.com/chart?cht=qr&chl=QRUPRC%3A 的 URL,它将返回一个条形码图像给我,但该图像并没有真正物理存储在 google 的文件服务器中 - 它是生成的。我想这就是它的意思 所以基本上您希望[NSData dataWithContentsOfURL:myURLHere] 提供您在 RAM 中已有的数据,而不是从文件中读取数据? NSData 的文档对data:// 作为受支持的 URL 协议进行了一些引用,但我找不到任何有关其工作原理的文档。很可能只是十六进制字符串形式的数据? 【参考方案1】:

NSURL 支持 data:// URL-Scheme (RFC 2397)。 该方案允许您以

的形式构建 URL
data://data:MIME-Type;base64,<data>

一个有效的 Cocoa 示例是:

NSImage* img = [NSImage imageNamed:@"img"];
NSData* imgData = [img TIFFRepresentation];
NSString* dataFormatString = @"data:image/png;base64,%@";
NSString* dataString = [NSString stringWithFormat:dataFormatString, [imgData base64EncodedStringWithOptions:0]];
NSURL* dataURL = [NSURL URLWithString:dataString];

由于 base64 编码的性质,使用数据 URL 传递大型二进制 blob 可能效率有点低。

您还可以实现专门处理您的数据的自定义NSURLProtocol。 Apple 有一些使用自定义协议传递图像对象的示例代码:https://developer.apple.com/library/mac/samplecode/SpecialPictureProtocol/Introduction/Intro.html#//apple_ref/doc/uid/DTS10003816

【讨论】:

另一个例子:[NSString stringWithContentsOfURL:[NSURL URLWithString:@"data:text/plain;base64,aGVsbG8gd29ybGQ="] encoding:NSUTF8StringEncoding error:NULL]; 给你@"hello world"。不是太低效,与 ASCII 相比只多出 4 个字节。 谢谢。 data: 协议绝对适用于较小的缓冲区(如果有人感兴趣,我在这里编写了一个小型协议:github.com/bzotto/NSURL-DataAdditions)。自定义 NSURLProtocol 方式可能是这里的“最佳”答案,因为对于任何重要的事情,第一个选项在内存方面会非常浪费(并且需要一堆编码)。 我试图使用这个逻辑来创建一个内嵌 MP4 视频数据的 NSURL,然后用 AVFoundation 播放它。使用这种方法不会加载电影文件,也许 NSURLProtocol 会更成功。【参考方案2】:

您缺少的是 NSURLProtocol 类。大约需要三打代码,任何正确处理 URL 的代码都可以访问您的内存数据。阅读文档,这并不难,并且有可用的示例代码。

不幸的是,有些 API 将 NSURL 作为参数,但只能处理文件 URL。

【讨论】:

以上是关于我可以创建一个引用内存中 NSData 的 NSURL 吗?的主要内容,如果未能解决你的问题,请参考以下文章

NSURLSessionDataTask 内存警告应用程序崩溃

将十六进制值存储到 NSData

Block 循环引用

如何在Objective C中使用NSData创建json对象?

我可以在另一个 NSData 中存档 NSData 对象而不损坏数据吗?

在Swift中从NSString创建NSData