あなたは、VC(緑)を持っており、それがパネル(黄色)「ホルダー」このビューコントローラは "willSet/didSet"ペアでリークしますか?
あなたは10の異なるビュー・コントローラ...価格、販売、証券、トラック、ドライバー、パレットがあるとしていますあなたはイエローエリアに一度に1つずつ入れようとしています。これは、動的に我々がcurrent
に現在のVC 1を保持するストーリーボード
instantiateViewController(withIdentifier: "PricesID") as! Prices
から各VCをロードします。ここでは、それらの "スワップ"を可能にするコードです...
>>これは間違っています。このコードを使用しないでください< <
サルタンが以下で説明することをしなければなりません。
var current: UIViewController? = nil {
willSet {
// recall that the property name ("current") means the "old" one in willSet
if (current != nil) {
current!.willMove(toParentViewController: nil)
current!.view.removeFromSuperview()
current!.removeFromParentViewController()
// "!! point X !!"
}
}
didSet {
// recall that the property name ("current") means the "new" one in didSet
if (current != nil) {
current!.willMove(toParentViewController: self)
holder.addSubview(current!.view)
current!.view.bindEdgesToSuperview()
current!.didMove(toParentViewController: self)
}
}
}
>>>>>>>>重要! < < < < < < < < <
また、あなたはこのような何かをすれば、緑のページが行われたときに、黄色のビューコントローラを取り除くために不可欠であり、注意してください。 current
がそれを保持し、緑のページが解放されることはありませんそれ以外の場合:
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
current = nil
super.dismiss(animated: flag, completion: completion)
}
継続、あなたはこのようにcurrent
プロパティを使用したい:
func showPrices() {
current = s.instantiateViewController(withIdentifier: "PricesID") as! Prices
}
func showSales() {
current = s.instantiateViewController(withIdentifier: "SalesID") as! Sales
}
しかし、予告「点X」を考えます。通常は、削除するView Controllerを必ずnilに設定します。
blah this, blah that
blah.removeFromParentViewController()
blah = nil
しかし、私は実際には "willSet"コードブロックの中に現在の値を設定することはできません。そして、私はそれがちょうど何か(didSetの中)に設定されようとしていることに感謝します。しかし、それはちょっと変わったようです。何が欠けている?あなたは計算されたプロパティでこのようなことをすることができますか?
最終使用可能なバージョン..... Sulthanのアプローチを使用して
、これは、かなりのテストの後に完璧に動作します。だから、これはうまく機能
このような// change yellow area to "Prices"
current = s.instantiateViewController(withIdentifier: "PricesID") as! Prices
// change yellow area to "Stock"
current = s.instantiateViewController(withIdentifier: "StickID") as! Stock
を呼び出す
...
var current: UIViewController? = nil { // ESSENTIAL to nil on dismiss
didSet {
guard current != oldValue else { return }
oldValue?.willMove(toParentViewController: nil)
if (current != nil) {
addChildViewController(current!)
holder.addSubview(current!.view)
current!.view.bindEdgesToSuperview()
}
oldValue?.view.removeFromSuperview()
oldValue?.removeFromParentViewController()
if (current != nil) {
current!.didMove(toParentViewController: self)
}
}
// courtesy http://stackoverflow.com/a/41900263/294884
}
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
// ESSENTIAL to nil on dismiss
current = nil
super.dismiss(animated: flag, completion: completion)
}
セッターオブザーバーを使用しているということは、プロパティーが何かに設定されているということです。つまり、nilか他のビューコントローラーであるということです。では、 'willSet'と' didSet' makeの間の中間段階で 'nil'をどのような違いで割り当てることができるでしょうか?また、保持サイクルを持たない限り、明示的に 'nil'への参照を設定する必要はありません - 保持カウントは範囲外になったときに減少し、強い参照が残っていなければ割り当てが解除されます。 – Hamish
@ハミッシュ...「違いはな... ...まあ、スマートな人とチェックするのはいつも良いことです。 :) – Fattie
@ハミッシュ - あなたの2番目のポイントについて。うーん、現在の*はそれに対する強い参照です。プロパティを脇に置いておきます。クラスのある時点で "current = instantiateViewController ..."とすると、最終的に結局そのようなことはありません。単にremoveFromParentViewController() 'はそれを解放しません、私は信じて???? – Fattie