我遇到了一个问题,我的 Monotouch 应用程序有时会在收到内存警告后崩溃。请参阅下面的堆栈跟踪。
收到内存警告。等级=2
DTMobileIS [2299]:_memoryNotification:{
OSMemoryNotificationLevel = 2;
时间戳=“2011-04-11 14:29:09 +0000”;
}
顶级异常:System.MissingMethodException:未找到 Myapp.UI.BoardController::.ctor(System.IntPtr) 的构造函数
在 System.Activator.CreateInstance (System.Type 类型,BindingFlags bindingAttr,System.Reflection.Binder binder,System.Object[] args,System.Globalization.CultureInfo 文化,System.Object[] activationAttributes)[0x00000] 在:0
在 System.Activator.CreateInstance (System.Type 类型,System.Object[] args,System.Object[] activationAttributes)[0x00000] 在:0
在 System.Activator.CreateInstance(System.Type 类型,System.Object[] args)[0x00000] in :0
在 MonoTouch.ObjCRuntime.Runtime.ConstructNSObject (IntPtr ptr, IntPtr klass) [0x00000] in :0
在 MonoTouch.ObjCRuntime.Runtime.GetNSObject (IntPtr ptr) [0x00000] in :0
在 MonoTouch.ObjCRuntime.Runtime.GetNSObjectWrapped (IntPtr ptr) [0x00000] in :0
在(包装器 native 到托管)MonoTouch.ObjCRuntime.Runtime:GetNSObjectWrapped (intptr)
在 MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00000] in :0
在/Users/haakon/Code/Myapp-work/iOS/Myapp.Free/Myapp.Free/Main.cs:12 中的 Myapp.Free.Application.Main (System.String[] args) [0x00000]
堆栈跟踪是正确的,因为指示的类(BoardController,它是 UIViewController 子类)缺少采用 IntPtr 参数的构造函数。但这是故意的,因为我在我的应用程序中根本不使用 Interface Builder。那么为什么会这样呢?
我确实发现了一个类似的问题,似乎表明如果您允许您的 View (或可能的 View Controller )被垃圾收集,这可能会发生。但我不明白这怎么会发生在这里。一些背景知识:我的应用程序委托(delegate)持有对导航 Controller 的强引用,而导航 Controller 又持有对导航堆栈中 Root View Controller 的强引用。这个 Root View Controller 还持有对 BoardController 实例的强引用。所以我不明白 BoardController 怎么可能被垃圾收集。
有任何想法吗?
最佳答案
IntPtr 构造函数在需要将 native 对象呈现给托管对象时使用。在这种特殊情况下,您可以像这样创建:
var foo = new Foo ();
SomeObject.Property = foo;
这会将 Foo 对象分配给属性,但如果 Property 是 Objective-C 对象,如果您不保留对“foo”的引用,那么 Mono 的 GC 将继续处理托管 Foo 和非托管 Foo 之间的链接.
然后,稍后,您尝试检索它:
var bar = SomeObject.Property;
在这里,MonoTouch 将知道除了映射到它之外不再存在托管对象,因此它必须构造一个新对象,但它所拥有的只是 Objective-C 代码的 IntPtr。这就是你需要构造函数的原因。
您可能很想只添加 native 构造函数,这在许多情况下都很好,但如果您的对象在托管世界中存储了自己的状态,那么就会出现问题,例如:
public class Foo : UIView {
string Name;
public Foo () { Name= "Hello"; }
public Foo (IntPtr ptr) : base (ptr) {}
}
在这种情况下,IntPtr 构造函数不能仅从 IntPtr 完全重构托管对象及其状态。因此,问题的可能根源是您没有保留对对象的引用。
因此,真正的解决方法是:在托管代码中保留对 BoardController 的引用,以防止在以后仍要使用该对象时收集该对象。
关于xamarin.ios - 找不到 ViewController::.ctor(System.IntPtr) 的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5623223/