2

PFUser「firstName」と「lastName」に2つの追加の列があります。彼らはきちんと節約しています。データブラウザでデータを見ることができます。

PFUsersのNSArrayを持つプロパティを持つ別のPFObject「クラス」があります。PFObjectのクラスメソッド+fetchAllIfNeededInBackground: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のブロックコールバックに渡されるfetchedObjectsの配列にアクセスしてもスローされませんが、元々+fetchAllIfNeededInBackgroundに渡された実際の配列にアクセスするとスローされます。

呼び出しの前にfetchIfNeededを呼び出すと問題が解決しますが、なぜですか?データはすでにそこにあります。PFUsersのコレクションを所有するPFObjectを更新しないという点で、+ fetchAllIfNeededInBackgroundを理解できませんか?

4

2 に答える 2

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]…。

于 2012-04-24T08:09:08.443 に答える
1

あなたが説明していることはうまくいくはずです。 fetchAllIfNeeded配列自体のオブジェクトを更新するため、どのようにアクセスしてもかまいません。親を介してそれらにアクセスしていると言いますPFObjectが、デバッガーの出力は配列を介して直接アクセスを示しています。PFObject配列が現在のメンバーを指していない可能性はありますか?

デバッグ中に試すことができることの1つはisDataAvailable、のインスタンスを呼び出すことです。これは、の名前の後と、名前にアクセスする直前PFUserの両方で行われます。fetchAllIfNeededの呼び出し後、fetchAllIfNeeded配列のすべての要素に対してisDataAvailable戻る必要があります。YES名前にアクセスしてもそれでも返さYESれる場合は、このエラーは発生しないはずです。

それ以外の場合は、問題を再現する最小限のコードサンプルを提供できれば、さらにデバッグできれば幸いです。

ありがとう、

于 2012-04-23T17:51:47.627 に答える