2015-05-22 42 views
1

我将我的PFQuery对象的缓存策略设置为kPFCachePolicyCacheThenNetwork,但缓存始终保持为空。有人能帮我解决发生了什么事吗?PFQuery缓存始终为空

下面的代码返回缓存的结果空

-(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 

    }]; 

} 

回答

1

为了获得缓存的结果,查询需要匹配(或等于)先前查询结果被缓存的位置。该问题中发布的查询每次都有所不同,因为它的限定条件是[NSDate date]

为确保查询具有缓存的结果,请保留相同的PFQuery对象。如果你设置了kPFCachePolicyCacheThenNetwork,并且第二次运行find ...,你会得到一个缓存的结果。

编辑 - 解决此问题取决于系统对时间的敏感程度。让我们来看看这个问题:给我未过期的MySpecialClass实例,未来的未来意味着到期。

让我们以本地缓存的用法来表示,我希望有时可以进行快速查询和/或离线操作,并且我愿意相对于服务器上的内容交易真相(也许服务器不会获得新的无论如何,经常使用MySpecialClass的实例)。

在一定程度上,这些东西都是真实的,你可以有两种类型的查询解决的OP问题:

1)刷新查询,完成次数减少,这吹走缓存,并获取最新的未到期从服务器的东西。此查询完全按照OP代码实现,但使用默认缓存策略:仅限网络。

2)维护查询更频繁,依赖于缓存,但运行速度快且脱机。这个查询仍然希望省略我的特殊类的过期实例,但我们在查询后的代码中执行此操作。实现此查询是坚持一个属性(至少在执行过程中,可能执行之间,但是这是一个不同的主题),并使用高速缓存则网络如下:

@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); 
    }]; 
} 

关于什么的高速缓存,则─不错网络功能是,在连接的情况下,您的维护查询仍然与服务器保持相对最新,因为在查询之后,默默无闻地(如果可能)真正的查询已经完成,并且出现新的实例。当然,有些会过期,因为时间已经推进了,但之后我们会用内存中的过滤器来处理。

+0

谢谢@danh任何解决这个问题?除本地数据存储外 – fzkl

+0

@fzkl - 当然。回答不太简单,但我做得最好。 – danh

+0

非常感谢@danh – fzkl

0

根据文档,kPFCachePolicyCacheThenNetwork不应从缓存中返回,第一次所有的时间。第一次在返回之前它应该击中网络。可能是你有不好的缓存数据或什么?

  • 你还可以确认查询返回正常,但不设置cachePolicy吗?

  • 其他选项是尝试从设备上删除应用程序并再次运行,以便清除缓存。如果设备上存在缓存数据不佳的问题。

+0

感谢您的回应,但它首先从缓存中返回,然后返回文档中所述的网络。查询总是返回,但缓存将为空。CacheThenNetwork:查询首先从缓存中加载,然后从网络加载。在这种情况下,回调实际上会被调用两次 - 首先是缓存结果,然后是网络结果。 – fzkl