2011-04-12 31 views
2

問題的標題可能聽起來很蠢,但我有beenw琢磨一下以下問題:爲什麼我必須保留一個對我的UIViewController的引用來防止它被垃圾收集?

  • 添加UIView到應用程序的窗口。它不會旋轉,因爲沒有控制器實現ShouldAutoRotateToInterfaceOrientation():window.AddSubView(myView);
  • 現在讓一個UIViewController在LoadView()覆蓋ShouldAutoRotateToInterfaceOrientation()中創建其視圖。然後執行此操作:window.AddSubView(myController.View);

在後一種情況下視圖按預期旋轉。爲什麼?因爲它的視圖控制器告訴它這樣做。 但是,視圖如何知道它屬於哪個控制器?我沒有告訴它!從ObjC的人,我瞭解到,每個視圖都有一個「_ viewDelegate」屬性,它返回視圖的控制器。 但是,如果這是真的,爲什麼我必須保留一個myController的引用,最好在成員變量,以防止它被垃圾收集?我在AppDelegate.cs中的測試用例:

public static AddView() 
{ 
    var myController = new MyController(); 
    window.AddSubView(myController.View); 
} 

該視圖將是第一次正確,然後控制器似乎已經消失。但是,下面的代碼按預期工作:

var myController = null; 
public static AddView() 
{ 
    this.myController = new MyController(); 
    window.AddSubView(myController.View); 
} 

回答

3

的MonoTouch是建立在它的核心是使用引用計數作爲它的內存管理的iOS框架的頂部。即使在添加垃圾收集之後,它也不會影響底層框架。在UIView的情況下,它確實擁有對其UIViewController的引用,並且控制器被垃圾收集的原因是因爲iOS中的所有委託都被賦值並且不被保留。蘋果內存管理指南在「對對象的弱引用」下更詳細地解釋了這一點:http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmObjectOwnership.html%23//apple_ref/doc/uid/20000043-BEHDEDDB

希望這有助於。

+0

太棒了,謝謝!我知道你鏈接的文件,但我似乎錯過了代表被分配而沒有保留。這當然解釋了它! 現在剩下的唯一開放的事情是:爲什麼這個「_viewDelegate」屬性是這樣一個祕密,並且如果視圖已經知道它的控制器,所有人都會將「this」(作爲UIViewController)傳遞給視圖。但是:不同的話題。 – Krumelur 2011-04-12 21:39:11

+0

通常你不應該需要這些信息。設計模式是讓數據從您的控制器流入視圖,而不是。 UIView只應該負責顯示你的數據。 UIViewController負責管理數據並響應用戶操作。如果你需要聽UIControl事件,那麼你應該在viewdidload中設置它們,並在viewdidunload和dealloc中刪除它們。 – 2011-04-12 21:54:37

+0

是的,但是如果我的控制器管理一個UITableView並且實現了視圖的GetCell(),那麼向控制器請求位置x處的數據是實際可行的,因此我需要控制器參考。 – Krumelur 2011-04-12 21:56:45

相關問題