0

在我用于 iPhone 的 Monotouch 应用程序中,我试图将分段控制器添加到 UITableViewCell 以充当每行中值的切换。一切都正确显示,并且第一行在单击时最初会正常工作。但是,在该行离开屏幕并重新加载后,如果我再次单击分段控制器,则会收到异常:

由于未处理的异常而终止运行时 [错误] FATAL UNHANDLED EXCEPTION: System.Exception: Selector 从objective-c 对已被 GC 处理的 MonoTouch.UIKit.UIControlEventProxy (0x16D793C0) 类型的托管对象调用---> System.MissingMethodException : 没有找到 MonoTouch.UIKit.UIControlEventProxy::.ctor(System.IntPtr) 的构造函数

我听说过使用 Monotouch 的人尝试将按钮放在表格单元格中的类似问题。一般建议是将每个表格单元格添加到列表中以防止其被垃圾收集,但这对我不起作用。

有没有办法解决这个问题?

这是我的 GetCell 代码的简化版本:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
        {

            Hashtable rowData = dataList [indexPath.Row];
            FilterListToggleCell cell;
            cell = (FilterListToggleCell)tableView.DequeueReusableCell ("FilterTogglePlusCell");


            cacheList.Add(cell.Toggle);//cache only the segcontrol
                            //cacheList.Add(cell);//also previously tried caching the whole cell


            cell.Title.Text = (string)rowData["title"];
            if(additionalFields.Contains((string)rowData["key"])){
                cell.Toggle.SelectedSegment = 0;
            } else {
                cell.Toggle.SelectedSegment = 1;

            }



            cell.Toggle.ValueChanged += (sender, e) => {
                UISegmentedControl toggle = (UISegmentedControl)sender;

                if(toggle.SelectedSegment == 0){
                    Console.WriteLine("Toggle YES");
                } else {
                    Console.WriteLine("Toggle NO");
                }

            };



            cell.Toggle.Tag = indexPath.Row;

            return cell;

        }
4

2 回答 2

0

根据来自以下问题的信息,我能够在不需要额外缓存的情况下完成这项工作:如何从事件中删除/注销事件处理程序?

ValueChanged 行被替换为:

cell.Toggle.AddTarget(this, new Selector("ToggleChange"),UIControlEvent.ValueChanged);

另一个方法被添加到我的 UITableViewDataSource

[Export ("ToggleChange")]
void OnChange(UISementedControl toggle){
    if(toggle.SelectedSegment == 0){
        Console.WriteLine("Toggle YES");
    } else {
        Console.WriteLine("Toggle NO");
    }
}
于 2013-01-08T15:30:09.703 回答
0

你说的基本情况是对的。发生这种情况是因为没有对您从方法返回的的托管引用。因此,GC 可以收集并释放它(这将导致诸如想要回调托管实例的事件之类的问题)。有关更多详细信息,请参阅此答案UITableViewCellGetCell

现在我不确定为什么这种方法对你不起作用。但是您上面的代码似乎不完整,例如

cell = (FilterListToggleCell)tableView.DequeueReusableCell ("FilterTogglePlusCell");

可以返回null,这是您应该创建更多单元格的时间(实际上,没有条件可以实际创建任何新单元格,因此没有任何东西可以重复使用)。

您的下一行将抛出一个NullReferenceExceptionwhen cellis null (因为cell.Toggle)。

请注意,这并不能解释您的崩溃 - 我怀疑缺少一些使其工作的代码(创建单元格)并且可能无法正确缓存它们。

于 2013-01-07T20:10:15.690 回答