2015-04-20 30 views
1

OSX Yosemite在NSURL上引入了一个非常方便的属性:NSURLDocumentIdentifierKey为什么NSURL的NSURLDocumentIdentifierKey(几乎)总是零?

从文档报价:

NSURLDocumentIdentifierKey

The document identifier returned as an NSNumber (read-only). The document identifier is a value assigned by the kernel to a file or directory. This value is used to identify the document regardless of where it is moved on a volume. The identifier persists across system restarts. It is not transferred when the file is copied, but it survives "safe save” operations. For example, it remains on the path to which it was assigned, even after calling the replaceItemAtURL:withItemAtURL:backupItemName:options:resultingItemURL:error: method. Document identifiers are only unique within a single volume. This property is not supported by all volumes.

Available in OS X v10.10 and iOS 8.0.

不幸的是,价值似乎主要零(除了看起来完全断开一个到另一个罕见的例子)。

特别是,该代码会抛出异常,在最后一行(在优胜美地10.10.3测试):

NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSArray *attributesFlags = @[NSURLNameKey, mNSURLDocumentIdentifierKey]; 

    NSDirectoryEnumerator *en = [fileManager enumeratorAtURL:[NSURL URLWithString:NSHomeDirectory()] 
            includingPropertiesForKeys:attributesFlags 
                options:NSDirectoryEnumerationSkipsHiddenFiles 
               errorHandler:^BOOL(NSURL *url, NSError *error) { 
                NSAssert(NO, @"An error has occured"); 
                return YES; 
               }]; 

    for(NSURL *URL in en) { 
     NSNumber *documentID = nil; 
     NSError *error = nil; 
     BOOL result = [URL getResourceValue:&documentID forKey:NSURLDocumentIdentifierKey error:&error]; \ 
     NSAssert(result == YES && error==nil, @"Unable to read property. Error: %@", error); \ 
     NSLog(@"Processing file: %@", URL); 


     // This will break most of the times 
     NSAssert(documentID != nil, @"Document ID should not be nil!!"); 
    } 

也许我误解的文件,但在我看来NSURLDocumentIdentifierKey应该可以上的每个文件在磁盘上。

+0

这里所涉及的沙盒? – stevesliva

+0

我不这么认为:我根本不使用沙盒。除非这是一个MAS专用功能,但我不这么认为。 – duhanebel

回答

0

显然,优胜美地只有在知道某物正试图追踪其身份(如版本或iCloud)时,才会将DocumentIdentifier分配给文件。

我没有看到任何方式与内核交谈,并告诉它开始跟踪你感兴趣的文件。我希望在未来的版本中有所改变,因为API已经在OS X 10.10上公开,而且在这一点上它几乎是无用的。

1

我在这个问题上提出了一个苹果的错误,并得到了我的报告的反馈。截至目前,有关跟踪DocumentIdentifier的信息尚未成为文档的一部分,但票证仍处于开放状态。

缺少的信息是,默认情况下文件系统不跟踪DocumentIdentifier。您必须通过在chflagsUF_TRACKED标志位上使用chflags设置每个要跟踪的文件上的标志来启用跟踪。

下面的脚本将打印DocumentIdentifier一个文件:

https://gist.github.com/cmittendorf/fac92272a941a9cc64d5

而且这个脚本将使跟踪DocumentIdentifier

https://gist.github.com/cmittendorf/b680d1a03aefa08583d7

+0

我想知道如果在很多文件上启用这个功能会对性能产生什么影响。 – duhanebel

+0

非常有趣。我也想知道会对性能产生什么影响。而且,如果它可以在网络文件系统上工作。 –