2016-04-18 76 views
0

NSObject呈現一個視圖控制器:爲什麼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是它的財產嗎?

更新:我面對的有效問題是myVC顯示了一個代表爲myObject的控件的視圖。因爲myObject被釋放,控件無法再調用委託,因爲我將委託作爲weak進行引用。但是,當我強烈提及代表myObject保持分配並且代表被調用時。但它爲代表使用了一個強有力的參考文件而聞起來很可疑。

+1

代表通常是弱引用,因此行爲是預期的。呈現的控制器不擁有代表! – Eiko

+2

體系結構問題。您的對象是您的控制器的所有者,但沒有人擁有該對象,因此它將被釋放。 – Sulthan

+1

可能是因爲沒有人持有對MyObject的引用......這是呈現/解散UIViewController的錯誤方式,爲什麼將它包裝到MyObject中?你應該從另一個ViewController實例中顯示一個viewController而沒有任何介體,並且你不會有任何代理問題 – Injectios

回答

1

ARC內存管理基於所有權。一旦一個對象不被任何其他對象所擁有,它就會被釋放。總是有一個根對象擁有所有其他的 - UIApplication

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

您可以創建其他的根對象(其他所有制樹),當然,例如:在應用程序中的所有對象的所有權可以用樹來描述通過使用單身人士。

如果您的實例不屬於此層次結構樹中的某個對象,它將被取消分配。因此,您應該以控制器僅由其他控制器擁有的方式構建您的所有權層次結構,而不是通過自定義對象。

如果您需要對所有者的引用,那通常是使用weak引用的時間,以避免週期性所有權。

另請注意,UIViewController需要在堆上留下一些重要的內存,所以一旦不需要時不要再引用它們。在呈現它們之前創建新實例更爲常見(儘管存在例外情況)。

+0

那麼,你會推薦什麼樣的「登錄視圖控制器」的最佳實踐,當用戶註銷時,可以在整個應用程序流程中隨時顯示?登錄視圖包含觸發委託中功能的按鈕,當前是NSObject。如果我從所有權樹中刪除NSObject,我必須在每個調用視圖控制器中移動配置。我只能想到將myObject替換爲另一個視圖控制器,它除了配置和顯示登錄視圖控制器之外什麼都不做,但看起來效率也不高。 – Manuel

+1

@Manuel我認爲你應該把這些東西放到應用程序委託中(例如,使用類別)或到根視圖控制器。根視圖控制器通常是處理這種事情的地方。您實際上是在您的代碼中訪問該控制器。 – Sulthan

相關問題