結局のところ、まったく難しいことではありません。私はこれを私の調査結果で更新しようとしましたが、これを更新し続けます。
非同期プロパティのゲッターはどのように動作する必要がありますか?
Perform asynchronous request
プロパティが利用できない場合set the property
。(遅延読み込み用)
- 利用可能になったらプロパティを返します。
課題:
ただし、ここで同期メソッドを使用しない理由のように混乱する可能性があります。
非同期リクエストがいつ完了するかは誰にもわかりませんが、それは、可用性ステータスの必要性全体が不明であることを意味するわけではありません。これには、ハードウェア、カーネルからより高いレベルの API まで、すべてのシステムにメカニズムがあります。これを伝える手段の 1 つとして、プロトコルとデリゲートを参照できます。
非同期プロパティにプロトコルとデリゲートを使用しないのはなぜですか?
- 参照するすべてのクラスでデリゲートの実装を強制する必要があります-> Not a getter。
- 他のクラスに、それが非同期プロパティであることを知られたくありません。データが必要な場合は、データが取得された方法の性質を知らずに、利用可能になったときに取得します。(UIをフリーズせずに明らかに)。
プロトコルとデリゲートを使用せずに、または同期呼び出しに変換せずに、これをどのように達成するのでしょうか?
答えは、条件変数を使用することです。この条件変数は、分岐に使用するものとは異なることに注意してください。スレッド セーフであり、コンパイラとカーネル レベルでサポートされている必要があります。
- NSCondition
公式ドキュメントから、
The NSCondition class implements a condition variable whose semantics follow
those used for POSIX-style conditions. A condition object acts as both a lock
and a checkpoint in a given thread. The lock protects your code while it tests
the condition and performs the task triggered by the condition. The checkpoint
behavior requires that the condition be true before the thread proceeds with its
task. While the condition is not true, the thread blocks. It remains blocked until
another thread signals the condition object.
私がしなければならなかったのは、デリゲートを使用せずに、この getter メソッドが非同期要求の完了を認識できるようにすることだけでした。
-(NSMutableDictionary*) myDictionary {
if(!_myDictionary) {
_myDicitonary = [self someOtherMethod];
}
return _myDictionary;
}
ロックと非同期リクエストは getter 自体に実装できますが、ロックの操作を簡単にするために抵抗しました。また、それはロジックの素晴らしい分離です:)
- (NSMutableDictionary *)someOtherMethod
{
NSCondition *lockForCompletion = [[NSCondition alloc] init];
__block BOOL available = NO;
__block NSMutableDictionary* tempDict = [[NSMutableDictionary alloc] init];
[lockForCompletion lock]; // acquire the lock
dispatch_async(queue, ^{
/* perform online request */
dispatch_sync(dispatch_get_main_queue(), ^{
[tempDict setObject:myResponse forKey:@"mykey" count:1];
available = YES;
[lockForCompletion signal];
});
});
while(!available) {
[lockForCompletion wait];
}
[lockForCompletion unlock];
return tempDict;
}
available
また、最初はブール述語はまったく必要ないように見えることも指摘したいと思いwait
ます。しかし、実際にはブール述語は、ドキュメントで説明されているように、ロックを維持する上で非常に重要な役割を果たします。
A boolean predicate is an important part of the semantics of using conditions
because of the way signaling works. Signaling a condition does not guarantee
that the condition itself is true. There are timing issues involved in signaling
that may cause false signals to appear. Using a predicate ensures that these
spurious signals do not cause you to perform work before it is safe to do so.
The predicate itself is simply a flag or other variable in your code that you test
in order to acquire a Boolean result.