PFQuery缓存一直为空
PFQuery cache is null all the time
我将 PFQuery 对象的缓存策略设置为 kPFCachePolicyCacheThenNetwork
,但缓存始终为空。谁能帮我看看这是怎么回事?
下面的代码returns缓存结果一直为空
-(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
}];
}
根据文档,kPFCachePolicyCacheThenNetwork 不应 return 第一次从缓存中获取。第一次它应该在 returning 之前访问网络。可能是你有坏的缓存数据或什么的?
您还可以确认查询 return 在不设置 cachePolicy 的情况下正常吗?
其他选项是尝试从设备中删除该应用程序,然后再次 运行 以清除缓存。如果设备上的缓存数据有问题。
为了获得缓存结果,查询需要匹配(或等于)先前缓存结果的查询。问题中发布的查询每次都不同,因为它由 [NSDate date]
.
限定
要确保查询具有缓存结果,请保持相同的 PFQuery
对象。如果您设置 kPFCachePolicyCacheThenNetwork
,然后 运行 再次查找...,您将获得缓存结果。
编辑 -
解决这个问题取决于系统对时间的敏感程度。让我们将查询理解为:给我未过期的 MySpecialClass 实例,其中未过期意味着将来会过期。
让我们以本地缓存的使用为例,我有时想要一个快速查询 and/or 离线操作,并且我愿意牺牲与服务器上的内容相关的真实性(也许服务器没有'无论如何,我不会经常获得 MySpecialClass 的新实例。
如果这些都是真的,您可以通过两种类型的查询来解决 OP 问题:
1) 刷新查询,执行频率较低,清除缓存并从服务器获取最新的未过期内容。此查询与 OP 代码中的实现完全相同,但使用默认缓存策略:仅网络。
2) 一个维护查询,执行得更频繁,它依赖于缓存,但 运行 速度快且离线。这个查询仍然想忽略我的特殊 class 的过期实例,但我们在查询后的代码中这样做。将此查询实现为持续存在的 属性(至少在执行期间,可能在执行之间,但这是一个不同的主题)并按如下方式使用缓存然后网络:
@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);
}];
}
先缓存后网络功能的好处在于,在连接的情况下,您的维护查询仍然与服务器保持相对最新,因为在查询之后,如果可能的话,真正的查询是静默的被制造出来,新的实例出现。当然有些会过期,因为时间已经向前推进了,但我们之后会用内存过滤器来处理这个问题。
我将 PFQuery 对象的缓存策略设置为 kPFCachePolicyCacheThenNetwork
,但缓存始终为空。谁能帮我看看这是怎么回事?
下面的代码returns缓存结果一直为空
-(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
}];
}
根据文档,kPFCachePolicyCacheThenNetwork 不应 return 第一次从缓存中获取。第一次它应该在 returning 之前访问网络。可能是你有坏的缓存数据或什么的?
您还可以确认查询 return 在不设置 cachePolicy 的情况下正常吗?
其他选项是尝试从设备中删除该应用程序,然后再次 运行 以清除缓存。如果设备上的缓存数据有问题。
为了获得缓存结果,查询需要匹配(或等于)先前缓存结果的查询。问题中发布的查询每次都不同,因为它由 [NSDate date]
.
要确保查询具有缓存结果,请保持相同的 PFQuery
对象。如果您设置 kPFCachePolicyCacheThenNetwork
,然后 运行 再次查找...,您将获得缓存结果。
编辑 - 解决这个问题取决于系统对时间的敏感程度。让我们将查询理解为:给我未过期的 MySpecialClass 实例,其中未过期意味着将来会过期。
让我们以本地缓存的使用为例,我有时想要一个快速查询 and/or 离线操作,并且我愿意牺牲与服务器上的内容相关的真实性(也许服务器没有'无论如何,我不会经常获得 MySpecialClass 的新实例。
如果这些都是真的,您可以通过两种类型的查询来解决 OP 问题:
1) 刷新查询,执行频率较低,清除缓存并从服务器获取最新的未过期内容。此查询与 OP 代码中的实现完全相同,但使用默认缓存策略:仅网络。
2) 一个维护查询,执行得更频繁,它依赖于缓存,但 运行 速度快且离线。这个查询仍然想忽略我的特殊 class 的过期实例,但我们在查询后的代码中这样做。将此查询实现为持续存在的 属性(至少在执行期间,可能在执行之间,但这是一个不同的主题)并按如下方式使用缓存然后网络:
@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);
}];
}
先缓存后网络功能的好处在于,在连接的情况下,您的维护查询仍然与服务器保持相对最新,因为在查询之后,如果可能的话,真正的查询是静默的被制造出来,新的实例出现。当然有些会过期,因为时间已经向前推进了,但我们之后会用内存过滤器来处理这个问题。