オプションのバインディングを使用すると、ロジックのブロック全体を常に同じ方法で実行できます。オプションの連鎖を複数回実行すると、何が起こるのかが不明確になる可能性があり、予期しない動作を引き起こす競合条件の影響を受ける可能性があります。
オプションのバインドを使用すると、アンラッピングしたものに新しい参照を作成することになります。これは一般的に強力な参照です。それはまた、他の症例から突然変異の影響を受けない地方の参考文献です。習慣によっても一般的にlet
です。したがって、それは生涯を通じて同じ価値を保持します。
あなたの例を考えてみましょう...しかし少し微調整してください。
これは、ナビゲーションコントローラは、
pushViewController)
で(そのナビゲーションスタックに新しいビューコントローラを追加するためとして、それ自体に等しいビューコントローラの
navigationController
プロパティに渡さセット起こっている。そして、そのビューコントローラがオフにポップされたときに
if let navigationController = self.navigationController {
// this should always pass
assert(navigationController === self.navigationController)
navigationController.popViewControllerAnimated(false)
// this next assert may fail if `self` refers to the top VC on the nav stack
assert(navigationController === self.navigationController)
// we now add self back onto the nav stack
navigationController.pushViewController(self, animated: false)
// this should also always pass:
assert(navigationController === self.navigationController)
}
積み重ね、それが戻っnil
にそのプロパティを設定します
さんが再びこれらのアサーションを投げ、オプションのチェインのアプローチを見てみましょう:。
let navController = navigationController
// this should always pass
assert(navController === navigationController)
// assuming navigationController does not evaluate to nil here
navigationController?.popViewControllerAnimated(false)
// this may fail if `self` is top VC on nav stack
assert(navController === navigationController)
// if above failed, it's because navigation controller will now evaluate to nil
// if so, then the following optional chain will fail and nothing will happen
navigationController?.pushViewController(self, animated: false)
// if the previous assert fail, then the previous push wasn't called
// and if the previous push wasn't called, then navigation controller is still nil
// and therefore this assert would also fail:
assert(navController === navigationController)
だからここに、私たちのINSTA self
のnceプロパティが、nil
に設定されています。これは、独自のメソッド呼び出しによって、オプションのバインディング&チェーニングの間の動作の違いを引き起こします。
しかし、現在のスレッドで独自のアクションでそのプロパティに変更を加えていない場合でも、前の行に有効な値を持っていても突然プロパティがnil
に評価されています。これをマルチスレッドコードで実行すると、値がnil
、またはその逆の値を持つプロパティが別のスレッドによって発生する可能性があります。
要するに、すべてまたはなしを確認する必要がある場合は、オプションバインディングを優先する必要があります。
ナビゲーションコントローラーが存在しないこの特定のコントローラーには何らかの状況がありますか?このプロパティはオプションですが、ナビゲーションコントローラ(Interface Builder)が常に存在する場合は、安全に展開できます。 – vadian