我通过继承UITableViewController
和UITableViewSource
(不是UITableViewDataSource
!!!)在MonoTouch中绘制表格视图。在我的视图控制器的构造函数中,我设置了表视图源:
TableView.Source = new CustomTableViewSource();
在我的CustomTableViewSource
中,我正在构建表格视图的单元格。除非我在iPhone模拟器中模拟内存警告,否则它的工作效果很好。如果视图被隐藏(例如,选中标签栏中的其他视图控制器),当我回来时,表格视图只是空白(白色背景,不再有桌面视图)。
但是,我在DidReceiveMemoryWarning
回调中什么也没做。我还尝试再次设置TableViewSource
viewWillAppear
(如果收到内存警告),但没有更多的成功......
是垃圾收集器问题吗?我知道在接收内存警告时会调用GC.Collect
。也许垃圾收集器只是丢掉我的视图,我需要再次完全显示它?
答案 0 :(得分:2)
您应该在ViewDidLoad方法中而不是在构造函数中初始化表源。加载视图控制器时调用该方法,然后每次在内存警告后需要重新创建控制器视图时调用该方法。
我做了一些测试,在内存警告后得到了类似的结果。但是,我只获得一个空表视图。当我再次在ViewWillAppear中设置表源时,表中会正常填充数据。
您在ViewWillAppear中的实现不起作用的事实让我觉得该方法甚至没有被调用。如果是这种情况,我猜你的表视图在需要的时候没有被重新创建。
在使用不是从XIB文件创建视图的控制器时,在某些情况下会发生这种情况。在这种情况下,您应该在LoadView方法中创建视图(不调用base.LoadView()):
public override void LoadView()
{
this.View = new UITableView(UIScreen.MainScreen.ApplicationFrame); //or something similar
}
我遇到了类似的问题(没有重新创建的表视图),包含导航控制器的复杂层次结构,包含导航控制器,包含视图控制器等。当我提供LoadView方法时,问题就解决了。
我猜对了;)
答案 1 :(得分:1)
当收到内存警告时,您将调用GC.Collect()
是对的。这是来自操作系统的严重警告,MonoTouch将尝试释放它自己的内存(如果可能)。你可以通过覆盖DidReceiveMemoryWarning
来扩展它,这样你的应用程序也可以释放它并不是绝对需要的任何内存。
对GC的调用(与任何其他调用一样)意味着可以收集和释放未引用的每个对象。现在不应该收集您的CustomTableViewSource
实例(除非您的TableView
是)。如有疑问,可以通过为类型添加终结器来检查这一点,例如
~CustomTableViewSource ()
{
Console.WriteLine ("~CustomTableViewSource");
}
然而,您的CustomTableViewSource
中的对象可以收集(如果未引用),因为您的表的其他部分(UI)可能是。没有看到源代码就无法分辨。
我建议你试着找出被释放的内容,然后从那里你应该看到需要保留引用(避免被收集)或需要重新创建的内容(如果某些实例是故意释放的)。
答案 2 :(得分:1)
总而言之,我的解决方案是:
public class LoginViewController : UITableViewController
{
LoginDataSource m_loginDataSource;
public LoginViewController(UITableViewStyle withStyle) : base(withStyle)
{
m_loginDataSource = new LoginDataSource(this);
}
public override void LoadView()
{
this.View = new UITableView(UIScreen.MainScreen.ApplicationFrame, UITableViewStyle.Grouped);
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
TableView.Source = m_loginDataSource;
}
}