【问题标题】:Saving NSDate to File With writeToURL使用 writeToURL 将 NSDate 保存到文件
【发布时间】:2013-10-23 05:28:29
【问题描述】:

我正在我正在开发的应用程序中构建图像缓存,其中缓存是 NSMutableDictionary。

字典最初是这样的:

NSMutableDictionary *imageCacheDictionary = [NSMutableDictionary initWithContentsOfURL:imageCacheURL];
//alloc-init imageCacheDictionary if nil
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSString *imageURLAsString = [imageURL absoluteString];
[imageCacheDictionary setObject:imageData forKey:imageURLAsString];
if ([imageCacheDictionary writeToURL:cacheURL atomically:YES]) {
    NSLog(@"file written");
} else {
    NSLog(@"file NOT written");
}

效果很好。

然后当我决定添加代码以将缓存保持在一定大小以下时,我尝试添加一个标签,以便我可以先删除最旧的照片。

NSMutableDictionary *imageCacheDictionary = [NSMutableDictionary initWithContentsOfURL:imageCacheURL];
//alloc-init imageCacheDictionary if nil
NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSString *imageURLAsString = [imageURL absoluteString];
NSDate *currentTime = [NSDate date];
NSDictionary *imageDataWithTime = @{currentTime : imageDataWithTime};
[imageCacheDictionary setObject:imageDataWithTime forKey:imageURLAsString];
if ([imageCacheDictionary writeToURL:cacheURL atomically:YES]) {
    NSLog(@"file written");
} else {
    NSLog(@"file NOT written");
}

这不起作用。

据我所知,NSDate 符合属性列表,因此 writeToURL 应该允许您写入磁盘,但不是。

然后我尝试使用 NSKeyedArchiver 将其转换为 NSData。

...
NSData *currentTimeAsData = [NSKeyedArchiver archivedDataWithRootObject:[NSDate date]];
NSDictionary *imageDataWithTime = @{currentTimeAsData : imageData};
...

还是不行。

但是如果我将 NSDate 对象转换为 NSString 或者只是用 NSString 替换它,它就可以正常工作。

...
NSString *currentTime = [[NSDate date] description];
NSDictionary *imageDataWithTime = @{currentTime : imageData};
...

或者:

...
NSString *currentTime = @"Hey! Now is now!";
NSDictionary *imageDateWithTime = @{currentTime : imageData};
...

所以....为什么?如果 NSDate 和 NSData 都符合属性列表,为什么它们都没有写入嵌套字典中的磁盘,而 NSString 写入正常?

【问题讨论】:

  • 能否请您也粘贴 imageURl?
  • 此链接可能对您有所帮助stackoverflow.com/questions/5361630/…
  • imageURL 是 VC 设置的一个属性,它创建了这个 VC 的 segue,所以在我的实际代码中它是 self.imageURL。

标签: ios objective-c nsdate nsdata


【解决方案1】:

属性列表键必须是字符串,不能是日期。 This page here 说:

虽然 NSDictionary 和 CFDictionary 对象允许它们的键是任何类型的对象,如果键不是字符串对象,则集合不是属性列表对象。

你需要的是字典里面的字典,例如:

NSDictionary *imageInfo = @{ @"date" : [NSDate date], @"data" : imageData };

NSDictionary *mainCacheDict = @{ imageURLAsString : imageInfo };

这样,缓存字典仍然有字符串 URL 作为键,但值是包含日期和图像数据的第二个字典(使用字符串键 @"date" 和 @"data" 访问)。这符合属性列表,因此您可以继续使用writeToFile: 和initWithContentsOfFile: 方法。

【讨论】:

  • 是的!谢谢你。这完全成功了。在查看 Property List 文档时,我完全错过了那句话。
【解决方案2】:

问题出在您在字典中制作的数据中。试试下面:-

NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
NSString *imageURLAsString = [imageURL absoluteString];
NSDate *currentTime = [NSDate date];
//Below your code has modified
  [imageCacheDictionary setObject:currentTime forKey:imageDataWithTime];
  NSDictionary *imageDataWithTime =[NSDictionary dictionaryWithObject:imageCacheDictionary forKey:imageURLAsString];

if ([imageDataWithTime writeToFile:@"yourPath" atomically:YES]) {
    NSLog(@"file written");
} else {
    NSLog(@"file NOT written");
}

【讨论】:

  • 我不认为我在我的代码中说得很清楚,所以我为此道歉:imageCacheDictionary 是一个从磁盘检索的 NSMutableDictionary,如果不是 nil,它已经包含 image : URL 配对,所以我需要只需添加我正在缓存的新图像,然后重新保存相同的字典。我在原始评论中修改了我的代码。
【解决方案3】:

试试这个:我修改了你的代码:

NSData *imageData = UIImageJPEGRepresentation(image, 1.0);
    NSDate *currentTime = [NSDate date];
    NSDictionary *imageDataWithTime = @{currentTime : imageDataWithTime};
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
    [archiver encodeObject:imageDataWithTime forKey:@"Some Key Value"];
    [archiver finishEncoding];
    if ([data writeToURL:cacheURL atomically:YES]) {
        NSLog(@"file written");
    } else {
        NSLog(@"file NOT written");
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2019-04-09
    相关资源
    最近更新 更多