Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 使用NSCoding缓存数据?_Ios_Objective C_Caching_Offline Caching_Nscoding - Fatal编程技术网

Ios 使用NSCoding缓存数据?

Ios 使用NSCoding缓存数据?,ios,objective-c,caching,offline-caching,nscoding,Ios,Objective C,Caching,Offline Caching,Nscoding,在我的应用程序中,我从服务器检索url数据。作为优化,我通过将数据存储到自定义类中来规范化数据,以便以后可以快速访问数据。但是,我需要在本地和脱机存储此类的实例,以便在已经从服务器检索数据的情况下避免从服务器检索数据。此外,网站每天都在变化,因此缓存的数据只有在来自同一天时才有用 这个场景适用于2个单独的类(总共4个对象),我尝试过用NSCoding保存这些数据,就像这样。(到目前为止,我只尝试实现一个对象,但我计划为每个对象创建一个单独的docPath) 但是,当我尝试运行此代码时,我收到一个

在我的应用程序中,我从服务器检索url数据。作为优化,我通过将数据存储到自定义类中来规范化数据,以便以后可以快速访问数据。但是,我需要在本地和脱机存储此类的实例,以便在已经从服务器检索数据的情况下避免从服务器检索数据。此外,网站每天都在变化,因此缓存的数据只有在来自同一天时才有用

这个场景适用于2个单独的类(总共4个对象),我尝试过用NSCoding保存这些数据,就像这样。(到目前为止,我只尝试实现一个对象,但我计划为每个对象创建一个单独的docPath)

但是,当我尝试运行此代码时,我收到一个
[Hours encodeWithCoder:]:无法识别的选择器发送到实例0
,因为我的类当前不支持NSCoding。在我需要手动编码自定义类的所有属性之后,我想确保NSCoding是解决数据缓存问题的理想方案

编辑:

下面是我当前创建url的方式

NSURL *url = [NSURL URLWithString:urlString];
NSData *pageData = [NSData dataWithContentsOfURL:url];

TL;DL;系统已经在为您缓存

当发出请求时,URL加载系统将检查共享URL缓存,以查看缓存中是否存在有效的匹配响应。如果有,它将使用它,而不是建立网络连接。这对您的网络代码是透明的,无论是从缓存中还是从网络中获得数据,其工作原理都是一样的。要使用磁盘,除了告诉
NSURLCache
之外,您不必执行任何操作:

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:(4 * 1024 * 1024) diskCapacity:(20 * 1024 * 1024) diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
这将允许它使用4MB RAM、20MB磁盘和磁盘上的默认缓存位置。这应该在应用程序启动时执行一次。 从那时起,
NSURLCache
将向内存和磁盘写入任何可缓存的网络响应。当它们过期或缓存空间不足时,它们将被删除。 网络连接如何使用缓存由
NSURLRequest
cachePolicy
决定。默认的
NSURLRequestUseProtocolCachePolicy
根据协议(HTTP)的规则使用缓存。HTTP响应包括关于响应有效时间的信息,并且此策略遵守这些规则。在大多数情况下,这工作得很好——除非与您通信的服务器错误地实现了HTTP响应缓存信息。 如果要更改缓存策略以不允许URL加载系统尝试从网络加载任何内容,请仅在设备的无线电处于脱机状态时执行此操作。如果设备处于飞行模式,您将使用不同的缓存策略构造
NSURLRequest
(假设您使用可达性来确定网络状态):

如果设备处于飞行模式,或者蜂窝或wifi都没有信号,这将使用策略
NSURLRequestReturnCacheDataDontLoad
NSURLRequestReturnCacheDataDontLoad
将从缓存加载响应(即使已过期),并且不会尝试访问网络中不在缓存中的项目


你可以在

中阅读更多关于这方面的内容,你知道它已经被缓存了,对吗?如果要在文件系统上缓存某些内容,请使用NSCachesDirectory而不是NSDocumentDirectory。在该目录中创建自己的子目录也是一个好主意。也许我的做法不对,但我认为最好存储自定义类,而不仅仅是原始服务器数据提取数据并将其传递给类的过程需要大量代码,所以我也希望通过Cachin消除这个过程。如果我没弄错,你还是要这么做。如果您只允许URL加载系统完成它的工作,那么您不必实现和测试NSCoding以及在此基础上的自定义缓存实现。因此,似乎我可以通过
连接:willCacheResponse:
确定是否缓存,但我仍然不确定如何检查缓存数据的日期。每次刷新缓存时,是否将日期存储在
NSUserDefaults
中?否,该方法告诉代理它将缓存响应。为了你想要的,你不应该实现它。让NSURLCache完成答案中描述的工作。这就是您所需要做的。它是否会自动检查缓存的数据是否是最新的?是的,它会检查缓存的响应是否有效。我尝试添加
NSURLCache*URLCache
,如您在回答中所述,但它仍然会调用服务器,而不是从缓存加载数据。我在问题中添加了详细信息,说明了我是如何初始化url的——我还想知道缓存是否仅限于iOS
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:(4 * 1024 * 1024) diskCapacity:(20 * 1024 * 1024) diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];
if (networkStatus == NotReachable){
    request = [[NSURLRequest alloc] initWithURL:someURL cachePolicy: NSURLRequestReturnCacheDataDontLoad timeoutInterval:timeout];
} else {
    request = [[NSURLRequest alloc] initWithURL:someURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:timeout];
}