iOS アプリケーションにタイマーを追加しようとしています。このために、次のコードを使用します。
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
namespace MyNamespace
{
[Register ("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{
UIWindow window;
public static NavigationController MyNavigationController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
RectangleF bounds = UIScreen.MainScreen.Bounds;
MyNavigationController = new NavigationController(bounds);
window = new UIWindow (bounds);
window.RootViewController = MyNavigationController;
window.MakeKeyAndVisible ();
return true;
}
}
public class NavigationController : UINavigationController
{
private RectangleF _bounds;
private RectangleF _viewPort;
public NavigationController(RectangleF bounds)
{
_bounds = bounds;
NavigationBar.BarStyle = UIBarStyle.Black;
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
_viewPort = new RectangleF(_bounds.Location, new SizeF(_bounds.Width, _bounds.Height - NavigationBar.Frame.Height));
ShowFirstView(); // Default to showing FirstViewController
}
public void ShowFirstView()
{
PushViewController(new FirstViewController(_viewPort), true);
}
public void ShowSecondView()
{
PushViewController(new SecondViewController(_viewPort), true);
}
}
public class FirstViewController : UIViewController
{
public FirstViewController(RectangleF bounds)
{
// Empty view
View = new UIView(bounds);
View.BackgroundColor = UIColor.White;
Title = "First View";
// Simple button to navigate to next view
UIButton button = UIButton.FromType(UIButtonType.RoundedRect);
button.Frame = new RectangleF(10,10,300,30);
button.SetTitle("Show next view", UIControlState.Normal);
button.TouchUpInside += (sender, e) => { AppDelegate.MyNavigationController.ShowSecondView(); };
View.AddSubview(button);
}
}
public class SecondViewController : UIViewController
{
private NSTimer _timer;
public SecondViewController(RectangleF bounds)
{
// Empty View
View = new UIView(bounds);
View.BackgroundColor = UIColor.Blue;
Title = "Second View";
// Create timer
_timer = NSTimer.CreateRepeatingScheduledTimer(2f, delegate { Console.WriteLine("Timer Fired"); });
}
}
}
このコードをシミュレーターで実行すると、期待どおりに動作し、2 秒ごとに「Timer Fired」がコンソールに出力されます。
ただし、Apple Instruments、特にAllocations Instrumentをアタッチすると、 Main.csで例外がスローさUIApplication.Main (args, null, "AppDelegate");
れます。
GC されたタイプ MonoTouch.Foundation.NSActionDispatcher (0x10AA2D50) のマネージド オブジェクトで、objective-c から呼び出されたセレクター
スタックトレース:
System.Exception: Selector invoked from objective-c on a managed object of type MonoTouch.Foundation.NSActionDispatcher (0x14FB5AC0) that has been GC'ed ---> System.Exception: No constructor found for MonoTouch.Foundation.NSActionDispatcher::.ctor(System.IntPtr)
at System.Activator.CreateInstance (System.Type type, BindingFlags bindingAttr, System.Reflection.Binder binder, System.Object[] args, System.Globalization.CultureInfo culture, System.Object[] activationAttributes) [0x000f1] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:280
at System.Activator.CreateInstance (System.Type type, System.Object[] args, System.Object[] activationAttributes) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:234
at System.Activator.CreateInstance (System.Type type, System.Object[] args) [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Activator.cs:229
at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x0000d] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:231
--- End of inner exception stack trace ---
at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00045] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:236
at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x0001f] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:280
at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:297
at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at MyNamescape.Application.Main (System.String[] args) [0x00000] in Main.cs:17
注意すべき重要事項:
- アプリは、通常の状況 (インストゥルメントなし) で、シミュレーターで正しく実行されます。
- この問題は、Allocations Instrument が監視している場合にのみ発生します。別の機器 (Leaks など) を使用すると、問題は発生しません。
- この問題は、タイマーが設定される前に割り当て手段を接続した場合にのみ発生します。タイマーが設定された後に割り当てインストルメントをアタッチすると、期待どおりに機能します。
- Allocation Instrument は、アプリケーションの他のビュー コントローラ全体で機能します
NSActionDispatcher
このコンテキストに関連して、またはMonoTouchでそうでなければ、多くの情報を見つけることができませんでした- 現在、物理デバイスでテストすることはできません。
したがって、これが Allocations Instrument の問題なのか、それとも自分のコードで深刻な問題を起こしているのかはわかりません。この問題に関するアドバイスは大歓迎です。
編集:問題を引き起こす最も単純な完全なアプリケーションの使用例を示すようにコードを更新しました。(スレッドの不必要な使用に関する PouPou のコメントに従って、タイマー コードを更新しました)
更新 (2013 年 1 月 17 日): iPad および iPhone シミュレーターのバージョン 5.0、5.1、および 6.0 を使用してこれを試しましたが、すべて同じ結果が得られました。
更新 (2013 年 1 月 18 日): Rolf の要求に従って、ネイティブ スタック フレームを追加しました。
2013-01-18 13:28:47.579 TestTimer[12196:c07] at MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00045] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:236
at MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x0001f] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:280
at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:297
at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at MyNamescape.Application.Main (System.String[] args) [0x00000] in Main.cs:16
2013-01-18 13:28:47.623 TestTimer[12196:c07] 0 TestTimer 0x00093a22 mono_handle_exception_internal_first_pass + 3058
1 TestTimer 0x00095102 mono_handle_exception_internal + 1602
2 TestTimer 0x00095c4f mono_handle_exception + 47
3 TestTimer 0x000dda72 mono_x86_throw_exception + 306
4 ??? 0x0b3e0f8f 0x0 + 188616591
at MonoTouch.ObjCRuntime.Runtime.GetNSObject (intptr) [0x0001f] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:280
at MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) [0x00000] in /Developer/MonoTouch/Source/monotouch/src/ObjCRuntime/Runtime.cs:297
at (wrapper native-to-managed) MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (intptr) <IL 0x00017, 0x00094>
8 TestTimer 0x00224873 get_managed_object_for_ptr + 115
9 TestTimer 0x00229700 monotouch_trampoline + 448
10 Foundation 0x019b9b90 __NSFireTimer + 97
11 CoreFoundation 0x01315376 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22
12 CoreFoundation 0x01314e06 __CFRunLoopDoTimer + 534
13 CoreFoundation 0x012fca82 __CFRunLoopRun + 1810
14 CoreFoundation 0x012fbf44 CFRunLoopRunSpecific + 276
15 CoreFoundation 0x012fbe1b CFRunLoopRunInMode + 123
16 GraphicsServices 0x04b807e3 GSEventRunModal + 88
17 GraphicsServices 0x04b80668 GSEventRun + 104
18 UIKit 0x0273965c UIApplicationMain + 1211
at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication.UIApplicationMain (int,string[],intptr,intptr) <IL 0x00056, 0x001f5>
at MonoTouch.UIKit.UIApplication.Main (string[],string,string) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
at MyNamescape.Application.Main (string[]) [0x00000] in Main.cs:16
at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <IL 0x00049, 0x0014e>
23 TestTimer 0x00010252 mono_jit_runtime_invoke + 722
24 TestTimer 0x0017478e mono_runtime_invoke + 126
25 TestTimer 0x00178be4 mono_runtime_exec_main + 420
26 TestTimer 0x00178f55 mono_runtime_run_main + 725
27 TestTimer 0x0006ba65 mono_jit_exec + 149
28 TestTimer 0x0021f65d main + 2013
29 TestTimer 0x00003125 start + 53