在Monotouch中单击SegmentedControl到UITableViewCell会导致SIGABRT

时间:2013-01-07 18:19:27

标签: uitableview xamarin.ios sigabrt

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

由于未处理的异常而终止运行时 [ERROR] FATAL UNHANDLED EXCEPTION:System.Exception:从已经过GC的MonoTouch.UIKit.UIControlEventProxy(0x16D793C0)类型的托管对象上的objective-c调用的选择器---> System.MissingMethodException:找不到MonoTouch.UIKit.UIControlEventProxy ::。ctor(System.IntPtr)的构造函数

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

有解决方案可以解决这个问题吗?

以下是我的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;

        }

2 个答案:

答案 0 :(得分:0)

你对基本条件是正确的。出现这种情况的原因是,您从UITableViewCell方法返回的GetCell没有托管引用。因此,GC可以收集并释放它(这将导致诸如想要回调给托管实例的事件之类的问题)。有关详细信息,请参阅此answer

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

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

可以返回null,这时你应该创建更多的单元格(事实上,你没有实际创建任何新单元格的条件,所以没有什么可以重复使用的。)

NullReferenceException为空时(由于cell),您的下一行将抛出cell.Toggle

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

答案 1 :(得分:0)

我能够在不需要基于此问题的信息的额外缓存的情况下实现此工作:How do I remove/unregister event handler from an event?

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");
    }
}