2011-05-27 17 views
1

這是使用MonoTouch時的問題。爲什麼我的UISwitch崩潰時,它是一個tableView.cell.AccessoryView

我正在嘗試使用具有UISwitch的單元格的TableView,但當點擊該開關時,該應用程序崩潰。爲了測試,我也 創建了一個開關,僅僅作爲TableView 本身的子視圖添加。兩個交換機之間的唯一區別是它們的父節點。 一個與TableView父項一起工作,單元中的一個作爲其點擊時的AccessoryView崩潰。

爲了測試,我創建了一個新的基於iPhone導航的應用程序 (DynUISwitch)。我只編輯所生成的RootViewController.xib.cs 如下:

using MonoTouch.UIKit; 
    using System; 
    using System.Drawing; 

    using MonoTouch.Foundation; 

    namespace DynUISwitch 
    { 
    partial class RootViewController : UITableViewController 
    { 
     public RootViewController (IntPtr handle) : base(handle) 
     { 
     } 

     public override void ViewDidLoad() 
     { 
     base.ViewDidLoad(); 
     RectangleF frame = new RectangleF (100f, 100f, 20f, 20f); 
     UISwitch uiSwitch = new UISwitch (frame); 
     uiSwitch.ValueChanged += delegate { 
      Console.WriteLine ("View Switch value now is {0}", uiSwitch.On); 
     }; 

     this.View.AddSubview (uiSwitch); 
     this.TableView.Source = new DataSource (this); 
     } 
     class DataSource : UITableViewSource 
     { 
     RootViewController controller; 

     public DataSource (RootViewController controller) 
     { 
      this.controller = controller; 
     } 
     public override int NumberOfSections (UITableView tableView) 
     { 
      return 1; 
     } 
     public override int RowsInSection (UITableView tableview, int section) 
     { 
      return 1; 
     } 
     public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) 
     { 
      string cellIdentifier = "Cell"; 
      var cell = tableView.DequeueReusableCell (cellIdentifier); 
      if (cell == null) 
      { 
      cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier); 
      } 
      RectangleF frame = new RectangleF (0f, 0f, 20f, 20f); 
      UISwitch uiSwitch = new UISwitch (frame); 
      uiSwitch.ValueChanged += delegate { 
      Console.WriteLine ("Cell Switch value is now {0}", uiSwitch.On); 
      }; 
      cell.AccessoryView = uiSwitch; 
      return cell; 
     } 
     } 
    } 
    } 

當運行該應用程序,我點擊中心UISwitch,所述一個直接 附連到的TableView。應用程序輸出窗口顯示委託人接收並處理點擊的 。然後我點擊 UiSwitch那是cell.AccessoryView,我立即得到 下列崩潰:

堆棧跟蹤:

at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x0009f, 0xffffffff> 
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x00038] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:26 
at MonoTouch.UIKit.UIApplication.Main (string[]) [0x00000] in /Users/plasma/Source/iphone/monotouch/UIKit/UIApplication.cs:31 
at DynUISwitch.Application.Main (string[]) [0x00000] in /Users/guivho/Mono/Learning/DynUISwitch/Main.cs:14 
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00050, 0xffffffff> 

本地堆棧跟蹤:

0 DynUISwitch       0x000d1965 mono_handle_native_sigsegv + 343 
1 DynUISwitch       0x0000ffb4 mono_sigsegv_signal_handler + 322 
2 libSystem.B.dylib     0x9666e45b _sigtramp + 43 
3 ???         0xffffffff 0x0 + 4294967295 
4 UIKit        0x01c981b5 -[UIControl sendAction:to:forEvent:] + 67 
5 UIKit        0x01c9a647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527 
6 UIKit        0x01ddcc6d -[UISwitch _onAnimationDidStop:finished:context:] + 201 
7 UIKit        0x01c3a665 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 294 
8 UIKit        0x01c3a4f7 -[UIViewAnimationState animationDidStop:finished:] + 77 
9 QuartzCore       0x030756cb _ZL23run_animation_callbacksdPv + 278 
10 QuartzCore       0x03075589 _ZN2CAL14timer_callbackEP16__CFRunLoopTimerPv + 157 
11 CoreFoundation      0x00e20fe3 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19 
12 CoreFoundation      0x00e22594 __CFRunLoopDoTimer + 1220 
13 CoreFoundation      0x00d7ecc9 __CFRunLoopRun + 1817 
14 CoreFoundation      0x00d7e240 CFRunLoopRunSpecific + 208 
15 CoreFoundation      0x00d7e161 CFRunLoopRunInMode + 97 
16 GraphicsServices     0x03ede268 GSEventRunModal + 217 
17 GraphicsServices     0x03ede32d GSEventRun + 115 
18 UIKit        0x01c1842e UIApplicationMain + 1160 
19 ???         0x07fe0744 0x0 + 134088516 
20 ???         0x07fe067a 0x0 + 134088314 
21 ???         0x07ef2b96 0x0 + 133114774 
22 ???         0x07ef2ae2 0x0 + 133114594 
23 ???         0x07ef2b6d 0x0 + 133114733 
24 DynUISwitch       0x0000fd6f mono_jit_runtime_invoke + 1332 
25 DynUISwitch       0x001ee239 mono_runtime_invoke + 137 
26 DynUISwitch       0x001f0920 mono_runtime_exec_main + 669 
27 DynUISwitch       0x001efd0a mono_runtime_run_main + 843 
28 DynUISwitch       0x000a3c62 mError connecting stdout and stderr (127.0.0.1:10001) 
ono_jit_exec + 200 
29 DynUISwitch       0x002a25eb main + 3838 
30 DynUISwitch       0x000030c9 _start + 208 
31 DynUISwitch       0x00002ff8 start + 40 
32 ???         0x00000002 0x0 + 2 

調試從gdb的信息:

/tmp/mono-gdb-commands.nzt3EM:1: Error in sourced command file: 
unable to debug self 

================================================================= 
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. 
================================================================= 

我已經做了t他在Objective-C/XCode應用程序中的某種東西(具有 UISwitch作爲TableCell的AccessoryView)。

任何建議爲什麼它不能在上面的演示應用程序?

回答

2

試試在類級別聲明

UISwitch uiSwitch; 

。有可能當你的方法超出範圍時,GC正在清理你的uiSwitch引用,這樣當委託發出時它的引用就不再存在了。很多人在MT 4.0開始時遇到了類似的問題。

+0

嗨賈森,這確實是一個GC問題。只需將UISwitch(或UISwitch [])聲明爲DataSource類的私有變量就足夠了。它可以在GetCell中分配,並且可以在GC中存活。代表比工作正常。沒有更多的崩潰。 – guivho 2011-05-27 19:58:32

0

注意:在您的代碼中,每當單元格被使用時,不僅在創建單元時,您將添加新的UISwitch。使用幾十項滾動列表可能足以使應用程序崩潰並導致堆棧溢出。

要解決該問題,請確保將UISwitch的創建移動到if (cell == null)語句中,以便只在創建新單元格時創建UISwitch,而不是在從緩存中重用時創建。

+0

這似乎是一個非常好的觀點。特定的列表是靜態的,總是在屏幕上,所以它認爲我甚至可以不用可重用的單元機制。我可以爲每個可能的索引路徑值分配一個單元/開關組合。但是你是對的,如果需要這樣的條件分配,所有資源必須在[code] if(cell == null)[code]中分配。感謝名單。 – guivho 2011-05-29 06:27:52

相關問題