Ios Monotouch UISwitch.valueChanged代理目标错误

Ios Monotouch UISwitch.valueChanged代理目标错误,ios,uitableview,event-handling,xamarin.ios,uiswitch,Ios,Uitableview,Event Handling,Xamarin.ios,Uiswitch,我目前正在使用Monotouch框架为IOS开发一个应用程序,该框架有一个UITableView,带有一个自定义的UITableViewCell(使用XCode设计),其中包含UISwitch 我通过UITableViewSource管理单元格,但在管理分配给单元格开关的事件UISwitch.ValueChanged的委托方法的回调时,我显然遇到了问题 以下是我正在编写的UITableViewSource代码,它可能更明确: // This class manages the T

我目前正在使用Monotouch框架为IOS开发一个应用程序,该框架有一个UITableView,带有一个自定义的UITableViewCell(使用XCode设计),其中包含UISwitch

我通过UITableViewSource管理单元格,但在管理分配给单元格开关的事件UISwitch.ValueChanged的委托方法的回调时,我显然遇到了问题

以下是我正在编写的UITableViewSource代码,它可能更明确:

        // This class manages the TableView content and its rows
    class MyTableViewDelegate : UITableViewSource
    {
        SatellitesViewController        satController;

        List<long>                      allocatedCells;

        public MyTableViewDelegate (SatellitesViewController controller)
        {
            satController = controller;
            allocatedCells = new List<long>();
        }

        public override int     RowsInSection (UITableView tableview, int section)
        {
            return satController.sats.Count;
        }

        // Called when the switch to show the satellite's display state is touched
        public void             showButtonHandler(object sender, EventArgs e)
        {
            System.Console.WriteLine("SHOW BUTTONHANDLER");
            if (sender != null)
            {
                CustomSwitch    switchButton = (CustomSwitch) sender;
                TLEForRedis     satToShow = this.satController.getSatTLEs(switchButton.idSat, false);

                if (satToShow != null)
                {
                    if (switchButton.On == true)
                        this.satController.glView.showSatellite(satToShow);
                    else
                        this.satController.glView.hideSatellite(satToShow.Id);
                }
            }
        }

        // Called when the switch to show the satellite's display state is touched
        public void             orbitButtonHandler(object sender, EventArgs e)
        {
            System.Console.WriteLine("ORBIT BUTTONHANDLER");
            if (sender != null)
            {
                CustomSwitch    orbitButton = (CustomSwitch) sender;
                TLEForRedis     satToShow = this.satController.getSatTLEs(orbitButton.idSat, false);

                if (satToShow != null)
                    this.satController.glView.setSatelliteOrbitDisplayState(satToShow.Id, orbitButton.On);
            }
        }

        //  Create the cell at indexPath
        public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
        {
            string          cellName;
            string          nibName;
                cellName = "PROTO_CELL";
                nibName = "CellView";   
            // Get the table cell which is described in the CellView.xib interface
            var cell = tableView.DequeueReusableCell(cellName) as CellView;

            if (cell == null)
            {
                cell = new CellView();
                var views = NSBundle.MainBundle.LoadNib(nibName, cell, null);
                cell = Runtime.GetNSObject( views.ValueAt(0) ) as CellView;
            }

            // Modify the cell with its own data
            SatsList sat = (SatsList) satController.sats [indexPath.Row];

            CustomSwitch    showButton = (CustomSwitch)cell.ViewWithTag(1);
            UILabel         satName = (UILabel)cell.ViewWithTag(2);
            UILabel         catalogNumber = (UILabel)cell.ViewWithTag(3);
            CustomSwitch    favoriteButton = (CustomSwitch)cell.ViewWithTag(4);
            CustomSwitch    orbitButton = (CustomSwitch)cell.ViewWithTag(5);

            UIColor         lightgrey = new UIColor(0.85f, 0.85f, 0.85f, 1.0f);
            tableView.BackgroundColor = lightgrey;

            if (sat != null)
            {
                satName.Text = sat.satName;
                catalogNumber.Text = string.Format("{0}", sat.catalogNumber);
            }
            else
                System.Console.WriteLine("[ERROR] Satellite was not found for row " + indexPath.Row);

            // Set switch state to on when the satellite is already being displayed
            if (this.satController.glView.checkForSatelliteExistency(sat.Id))
            {
                System.Console.WriteLine(sat.satName + "found");
                showButton.SetState(true, false);
                Satellite   sat3D = this.satController.glView.checkForSatelliteOrbit(sat.Id);
                if (sat3D.displayOrbit())
                    orbitButton.SetState(true, false);
            }
            else // force switch state to off when satellite is not displayed yet
            {   
                showButton.SetState(false, false);
                orbitButton.SetState(false, false);
            }
            favoriteButton.SetState(false, false);

            // Bind changing state switches' events in order to display or hide the corresponding satellite
            showButton.setData(sat.Id);
            favoriteButton.setData(sat.Id);
            orbitButton.setData(sat.Id);
            if (!this.allocatedCells.Contains(indexPath.Row))
            {
                showButton.ValueChanged += this.showButtonHandler;
                orbitButton.ValueChanged += this.orbitButtonHandler;
            }
            this.allocatedCells.Add(indexPath.Row);
            return cell;
        }
或以下堆栈跟踪:

Stacktrace:

  at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff>
  at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x00042] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:29
  at App.Application.Main (string[]) [0x0001b] in App/Main.cs:24
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff>

Native stacktrace:

0   App                      0x0009094c mono_handle_native_sigsegv + 284
1   App                      0x00005cd8 mono_sigsegv_signal_handler + 248
2   libSystem.B.dylib                   0x90d9c05b _sigtramp + 43
3   ???                                 0xffffffff 0x0 + 4294967295
4   UIKit                               0x0222e55a -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
5   UIKit                               0x022d3b76 -[UIControl sendAction:to:forEvent:] + 66
6   UIKit                               0x022d403f -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
7   UIKit                               0x02425a6c -[_UISwitchInternalView _sendActions] + 121
8   Foundation                          0x0173786d __NSFireDelayedPerform + 389
9   CoreFoundation                      0x01195966 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
10  CoreFoundation                      0x01195407 __CFRunLoopDoTimer + 551
11  CoreFoundation                      0x010f87c0 __CFRunLoopRun + 1888
12  CoreFoundation                      0x010f7db4 CFRunLoopRunSpecific + 212
13  CoreFoundation                      0x010f7ccb CFRunLoopRunInMode + 123
14  GraphicsServices                    0x04789879 GSEventRunModal + 207
15  GraphicsServices                    0x0478993e GSEventRun + 114
16  UIKit                               0x0222ba9b UIApplicationMain + 1175
17  ???                                 0x0ebdde65 0x0 + 247324261
18  ???                                 0x0ebdc550 0x0 + 247317840
19  ???                                 0x0b7f7bac 0x0 + 192904108
20  ???                                 0x0b7f7d86 0x0 + 192904582
21  App                      0x0000a042 mono_jit_runtime_invoke + 722
22  App                      0x00169f4e mono_runtime_invoke + 126
23  App                      0x0016e034 mono_runtime_exec_main + 420
24  App                      0x00173455 mono_runtime_run_main + 725
25  App                      0x00067245 mono_jit_exec + 149
26  App                      0x002116a5 main + 2837
27  App                      0x00003095 start + 53
28  ???                                 0x00000004 0x0 + 4

=================================================================
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries 
used by your application.
=================================================================
行,以便只注册一次代理,但结果相同。当单元格离开屏幕时,我是否需要删除该if并尝试“注销”代理

我希望你有一个想法,并毫不犹豫地发表你对这一切的意见/建议/评论


提前谢谢

好的,我发现我的代码有问题,这是由于绑定到交换机的代理造成的。实际上,我忘了注销屏幕外单元格的代理。 取消对ReuseableCell的查询并不会删除链接到单元格内容的委托=>这将导致调用我的showButtonHandler(sender,args)方法的发件人的引用发生了更改

因此,我的代码的解决方案是将最后一部分更改为:

// Bind changing state switches' events in order to display or hide the corresponding satellite
            showButton.setData(sat.Id);
            favoriteButton.setData(sat.Id);
            orbitButton.setData(sat.Id);

            showButton.ValueChanged -= this.showButtonHandler;
            orbitButton.ValueChanged -= this.orbitButtonHandler;
            showButton.ValueChanged += this.showButtonHandler;
            orbitButton.ValueChanged += this.orbitButtonHandler;
            return cell;
        }
在我的例子中,甚至不需要在旧的allocatedCells列表中注册单元格。 重新使用单元格后,旧的委托将从开关中删除(-=),并用新的引用替换(+=)


不管怎样,谢谢大家。

好的,我发现我的代码有问题,这是由于绑定到交换机的代理造成的。实际上,我忘了注销屏幕外单元格的代理。 取消对ReuseableCell的查询并不会删除链接到单元格内容的委托=>这将导致调用我的showButtonHandler(sender,args)方法的发件人的引用发生了更改

因此,我的代码的解决方案是将最后一部分更改为:

// Bind changing state switches' events in order to display or hide the corresponding satellite
            showButton.setData(sat.Id);
            favoriteButton.setData(sat.Id);
            orbitButton.setData(sat.Id);

            showButton.ValueChanged -= this.showButtonHandler;
            orbitButton.ValueChanged -= this.orbitButtonHandler;
            showButton.ValueChanged += this.showButtonHandler;
            orbitButton.ValueChanged += this.orbitButtonHandler;
            return cell;
        }
在我的例子中,甚至不需要在旧的allocatedCells列表中注册单元格。 重新使用单元格后,旧的委托将从开关中删除(-=),并用新的引用替换(+=)

不管怎样,谢谢大家

// Bind changing state switches' events in order to display or hide the corresponding satellite
            showButton.setData(sat.Id);
            favoriteButton.setData(sat.Id);
            orbitButton.setData(sat.Id);

            showButton.ValueChanged -= this.showButtonHandler;
            orbitButton.ValueChanged -= this.orbitButtonHandler;
            showButton.ValueChanged += this.showButtonHandler;
            orbitButton.ValueChanged += this.orbitButtonHandler;
            return cell;
        }