我将PFQuery对象的缓存策略设置为kPFCachePolicyCacheThenNetwork
,但缓存始终为空。有人可以帮我解决发生的事情吗?
以下代码始终将缓存的结果返回为空
-(void)doSomeQuery
{
PFQuery *query = [PFQuery queryWithClassName:kMySpecialClass];
[query whereKey:kDateExpires greaterThan:[NSDate date]];
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
NSLog(@"CACHED ? = %i",[query hasCachedResult]);//Nope, no matter what returns NO
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSLog(@"RETURNED: %@", objects);//1st cache (null) then network gets the data
}];
}
答案 0 :(得分:1)
为了获得缓存结果,查询需要匹配(或等于)缓存结果的早期查询。问题中发布的查询每次都不同,因为它由[NSDate date]
限定。
要确保查询具有缓存结果,请保留相同的PFQuery
对象。如果您设置kPFCachePolicyCacheThenNetwork
,并再次在其上运行find ...,您将获得缓存结果。
编辑 - 解决这个问题取决于系统对时间的敏感程度。让我们把查询的意思是:给我未过期的MySpecialClass实例,其中未过期意味着将来到期。
让我们使用本地缓存来表示,我有时需要快速查询和/或离线操作,并且我愿意相对于服务器上的内容交换真相(可能服务器没有获得新实例)非常经常MySpecialClass。)
在某些情况下,您可以通过两种类型的查询解决OP问题:
1)刷新查询,不常做,吹走缓存并从服务器获取最新的未到期的东西。此查询与OP代码完全相同,但使用默认缓存策略:仅限网络。
2)维护查询,更频繁地完成,依赖于缓存,但运行速度快且离线。此查询仍然希望省略我的特殊类的过期实例,但我们在查询后的代码中执行此操作。将此查询实现为持久存在的属性(至少在执行期间,可能在执行之间,但这是一个不同的主题)并使用cache-then-network,如下所示:
@property (strong) PFQuery *maintenanceQuery;
// lazily init
- (PFQuery *)maintenanceQuery {
if (!_maintenanceQuery) {
// op code, including cachePolicy = kPFCachePolicyCacheThenNetwork;
}
return _maintenanceQuery;
}
// based on some timing decision, either run the refresh query or...
- (void)runMaintenanceQuery:(void (^)(NSArray *, NSError *))completion {
[self.maintenanceQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
NSDate *now = [NSDate date];
NSPredicate *predicate = [NSPredicate predicateWithBlock:^BOOL(PFObject *mySpecialInstance, NSDictionary *bind){
NSDate *expiration = [mySpecialInstance valueForKey:kDateExpires];
return now == [expiration earlierDate:now];
}];
NSArray *unexpired = [objects filteredArrayUsingPredicate:predicate];
completion(unexpired, error);
}];
}
缓存然后网络功能有什么好处,在连接情况下,您的维护查询仍然与服务器保持相对最新,因为在查询之后,静默地,如果可能,真正的查询得到了,并出现新实例。有些人当然会过期,因为时间已经向前推进了,但我们之后会使用内存过滤器处理这个过程。
答案 1 :(得分:0)
根据文档,kPFCachePolicyCacheThenNetwork不应该首次从缓存中返回。第一次它应该返回网络之前。可能你有不好的缓存数据或什么?
您是否还可以确认查询返回正常而未设置cachePolicy?
其他选项是尝试从设备中删除应用程序并再次运行,以清除缓存。如果设备上有错误的缓存数据存在任何问题。