当尝试组合快速查看预览面板和安全范围的 URL 时,会出现 Cocoa 中选择不当、不可组合的抽象的问题。
我有一个具体的例子:
想象一下,我们正试图显示来自 MediaLibrary 的某些对象的预览(MediaLibrary.framework 允许应用程序通过方便的 API 浏览 iPhoto、Aperture... 和照片库)。
最简单直接的方法是调整“MLMediaObject”类(表示特定的照片或视频项目)以实现“QLPreviewItem”协议(可以传递给 QLPreviewPanel):
MLMediaObject+PreviewItem.h
#import <MediaLibrary/MLMediaObject.h>
#import <Quartz/Quartz.h>
@interface MLMediaObject (PreviewItem) <QLPreviewItem>
@end
MLMediaObject+PreviewItem.m
#import "MLMediaObject+PreviewItem.h"
@implementation MLMediaObject (PreviewItem)
- (NSURL*) previewItemURL
{
return self.URL;
}
- (NSString*) previewItemTitle
{
return self.name;
}
@end
简单的。现在想象以下 QLPreviewPanel 数据源实现:
相册视图控制器.m
- (NSInteger) numberOfPreviewItemsInPreviewPanel: (QLPreviewPanel*) panel
{
// 'currentAlbum' property contains the currently-represented MLMediaGroup object.
return self.currentAlbum.count;
}
- (id<QLPreviewItem>) previewPanel: (QLPreviewPanel*) panel previewItemAtIndex: (NSInteger) index
{
return self.currentAlbum[index];
}
到目前为止,一切都很好。但是,如果我们查看稀疏且通常具有误导性的 Apple 文档,我们可能会发现以下重要细节:
URL
媒体对象的位置。(只读)
此属性作为安全范围的 URL 提供。为了访问该 URL 所引用的文件,调用者必须在使用该 URL 访问该文件startAccessingSecurityScopedResource
之前和之后调用。stopAccessingSecurityScopedResource
因此,很明显,对资源的访问必须用startAccessingSecurityScopedResource
/stopAccessingSecurityScopedResource
调用对括起来。
问题是在给定当前QLPreviewPanelDataSource
协议定义的情况下我应该把这些调用放在哪里?访问资源取决于 QLPreviewPanel,而不是我的代码,但不幸的是,我几乎不会相信 Apple 更新了 QL 以在沙盒环境中运行。
startAccessingSecurityScopedResource
当呼叫返回时,我如何处理这些情况,NO
说明无法获得访问权限?
似乎当您尝试startAccessingSecurityScopedResource
访问已被访问的 URL 时,您会在返回时获得失败标志。就像,一切都很好,但是你得到一个错误标志。似乎这些开始/停止......调用必须精确配对,甚至禁止平衡嵌套。那么,当您获得返回时如何区分这两种可能性NO
:已被访问的安全范围 URL 和未能“解析”的安全范围 URL?
这是一个经过实验证明的事实,您的应用程序只能访问有限数量的安全范围 URL(在它静默停止工作之前,您可以获取大约 1500 个 URL)。那么,在将安全范围的 URL 传递给 QLPreviewPanel 之后,我应该如何正确放弃对它们的访问?什么时候这样做合适?在我看来,它是 QLPreviewPanel 类的私有实现细节,我无法对其内部工作做出任何假设。