2016-04-18 5 views
0

NSObjectビューコントローラを提示:myVCを画面上に提示し、まだ表示されている場合なぜNSObjectはUIViewControllerを表示している間に割り当て解除されますか?

class myObject: NSObject { 

    var myVC = UIViewController() 

    func present() { 
     let rootVC = UIApplication.sharedApplication().keyWindow!.rootViewController 
     rootVC.presentViewController(myVC, animated: animated, completion: nil) 
    } 
} 

はなぜmyObjectは(deinitが呼ばれた)割当て解除を得るのでしょうか? myVCはそのプロパティであるため、割り当てられてはいけませんか?

アップデート:私が直面している効果的な問題はmyVC、デリゲートmyObjectあるコントロールでビューを示すことです。 myObjectは割り当て解除されているため、コントロールは代理人をweakと参照しているため、コントロールは代理人をもう呼び出すことができません。しかし、私がデリゲートへの強い参照を持っているときには、myObjectが割り当てられ、デリゲートが呼び出されます。しかし、それは代表者のための強い参照を使用するために魚のようなにおいがする。

+1

通常、委任者は弱い参照であるため、動作は想定されています。提示されたコントローラはデリゲートを所有していません! – Eiko

+2

アーキテクチャの問題。オブジェクトはコントローラの所有者ですが、誰もそのオブジェクトを所有していないため、割り当てが解除されます。 – Sulthan

+1

おそらく、誰もMyObjectへの参照を保持していないので...これはUIViewControllerの表示/非表示の方法が間違っています。なぜMyObjectにラップするのですか?任意のメディエーターなしでViewControllerの別のインスタンスから1つのviewControllerを表示する必要があり、委任に関する問題は発生しません – Injectios

答えて

1

ARCメモリ管理は所有権に基づいています。あるオブジェクトが他のオブジェクトによって所有されていなければ、そのオブジェクトは割り当てを解除されます。他のすべてを所有するルートオブジェクトは常にあります。UIApplication

UIApplication 
    - UIApplicationDelegate 
     - rootViewController 
      - child controllers 
       - child controllers ... 
     - window 
      - subviews 
       - subviews ... 
     - ... other objects 

あなたは他のルートオブジェクト(他の所有権の木)を作成することができ、もちろん、例えば:アプリケーション内のすべてのオブジェクトの所有権は、木で記述することができますシングルトンを使用します。

インスタンスがこの階層ツリーのオブジェクトによって所有されていない場合、インスタンスは割り当て解除されます。したがって、コントローラがカスタムオブジェクトではなく他のコントローラによってのみ所有されるように所有権階層を構築する必要があります。

あなたが所有者への参照が必要な場合、それは通常、周期的な所有権を避けるために、weak参照を使用する時間です。

はまた、彼らが必要とされていないいったんそれらへの参照を維持するために非常に一般的ではありませんので、UIViewControllerは、ヒープ上にいくつかの重要なメモリを取ることに注意してください。新しいインスタンスを提示する前に新しいインスタンスを作成するのがより一般的です(ただし例外があります)。

+0

だから、ユーザーがログアウトしたときにアプリケーションフロー全体を通していつでも表示できる「ログインビューコントローラ」のベストプラクティスをお勧めしますか?ログインビューには、デリゲート、現在はNSObject内の関数をトリガーするボタンが含まれています。オーナーシップツリーからNSObjectを削除した場合は、呼び出し元のビューコントローラごとに設定を移動する必要がありました。 myObjectを、別のView Controllerで置き換えることだけ考えることができます。これは、ログインビューコントローラを設定して表示するだけですが、効率的ではないようです。 – Manuel

+1

@Manuel私はあなたがアプリケーションデリゲートに入れるべきだと思います。カテゴリを使用して)またはルートビューコントローラに送信します。通常、ルートビューコントローラはそのようなことを処理する場所です。あなたは実際にあなたのコードでそのコントローラにアクセスしています。 – Sulthan

関連する問題