在fetchAllIfNeeded之后调用objectForKey时,PFUser抛出NSInternalInconsistencyException

时间:2012-04-23 04:46:36

标签: objective-c ios ios5 parse-platform

我的PFUser上有两个额外的列" firstName"和" lastName"。他们保存得当;我可以在数据浏览器中看到数据。

我有另一个PFObject" class"它有一个带有NSArray PFUser的属性。我在PFObject上使用类方法 + fetchAllIededNeededInBackground:block:来获取PFUsers数组。在回调块中,我在数组中的每个PFUser上调用objectForKey:但是我通过拥有的PFObject访问它们。

// invited is the NSArray of PFUsers
self.whoCell.mainLabel.text = [[self.plan.invited objectAtIndex:0] 
                                                  objectForKey:@"firstName"];

调试器在objectForKey调用之前的断点处输出:

(lldb) po self.plan.invited
(NSArray *) $4 = 0x06e62a60 <__NSArrayM 0x6e62a60>(
<PFUser:GCCdPjCU2J> {
    firstName = Fake;
    lastName = Account;
    username = yyajnbafv53qw4yhjm9sfoiis;
}
)

编辑:添加self.plan.invited的实现,因为上述内容具有误导性。

- (NSArray*)invited
{
  // self.dataSource is a PFObject*
  return [self.dataSource objectForKey:INVITED_PROP];
}

然而,当上面调用 objectForKey:时,抛出了这个异常:

'NSInternalInconsistencyException', reason: 'Key "firstName" has no data.  Call fetchIfNeeded before getting its value.'

编辑:访问传递给 + fetchAllIfNeededInBackground 的块回调的fetchedObject数组不会抛出,但访问最初传递的实际数组 + fetchAllIfNeededInBackground 抛出。

在调用解决问题之前调用fetchIfNeeded,但为什么?数据已经存在。我是否错过理解 + fetchAllIfNeededInBackground ,因为它没有更新拥有PFUsers集合的PFObject?

2 个答案:

答案 0 :(得分:6)

我弄清楚发生了什么。让我用代码解释一下:

PFQuery *query = [PFQuery queryWithClassName:@"TestClass"];
PFObject *testObj = [query getObjectWithId:@"xWMyZ4YEGZ"];

// an array of PFUser "pointers" (pointers in Parse parlance)
NSLog(@"%@", [testObj objectForKey:@"userArrayProp"]);
[PFObject fetchAll:[testObj objectForKey:@"userArrayProp"]];

// now userArrayProp contains fully fetched PFObjects
NSLog(@"%@", [testObj objectForKey:@"userArrayProp"]);

对我来说,经过一段时间后,userArrayProp将恢复为“指针”数组,这让我感到困惑。我的问题是在PFObject上调用refresh会将获取的数组返回到指针数组。像这样:

PFQuery *query = [PFQuery queryWithClassName:@"TestClass"];
PFObject *testObj = [query getObjectWithId:@"xWMyZ4YEGZ"];

// an array of PFUser "pointers" (pointers in Parse parlance)
NSLog(@"%@", [testObj objectForKey:@"userArrayProp"]);
[PFObject fetchAll:[testObj objectForKey:@"userArrayProp"]];

// now userArrayProp contains fully fetched PFObjects
NSLog(@"%@", [testObj objectForKey:@"userArrayProp"]);

[testObj refresh];

// now userArrayProp contains pointers again :(
NSLog(@"%@", [testObj objectForKey:@"userArrayProp"]);

希望它说[PFObject refresh]在文档中做到了这一点......

答案 1 :(得分:1)

你所描述的应该可以正常工作。 fetchAllIfNeeded更新数组中的对象,因此访问它们的方式无关紧要。您说您是通过父PFObject访问它们,但您的调试器输出显示直接通过数组访问。数组是否可能未指向当前的PFObject成员?

调试时可以尝试的一件事是在isDataAvailable的{​​{1}}实例上调用PFUser,在fetchAllIfNeeded之后,以及在访问他们的名字和姓氏之前。调用fetchAllIfNeeded后,isDataAvailable应为数组的每个元素返回YES。如果在访问名称时仍然返回YES,则不应该出现此错误。

否则,如果您可以提供重现问题的最小代码示例,我很乐意进一步调试它。

谢谢,