Monotouch 在不可为空的对象上因 NullReferenceException 崩溃 [英] Monotouch crashes with NullReferenceException on non nullable object

查看:27
本文介绍了Monotouch 在不可为空的对象上因 NullReferenceException 崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是崩溃日志(简短):

Here is the crash log ( short ):

2013-04-24 19:56:24 +0000 Memotion 未处理的托管异常:未将对象引用设置为对象的实例 (System.NullReferenceException)
在 Pipedream.UI.UIElement.set_Size(Vector2 值)[0x00000] 中:0
在 Pipedream.UI.StageLayer..ctor (Pipedream.ComponentID id) [0x00000] 中:0
在 Pipedream.UI.Stage.CreateLayer (Pipedream.ComponentID id) [0x00000] 中:0

2013-04-24 19:56:24 +0000 Memotion Unhandled managed exception: Object reference not set to an instance of an object (System.NullReferenceException)
at Pipedream.UI.UIElement.set_Size (Vector2 value) [0x00000] in :0
at Pipedream.UI.StageLayer..ctor (Pipedream.ComponentID id) [0x00000] in :0
at Pipedream.UI.Stage.CreateLayer (Pipedream.ComponentID id) [0x00000] in :0

其实构造函数的代码是这样的:

Actually the code of the constructor looks like this:

internal StageLayer(ComponentID id)
    : base(id, ComponentLayer.System)
{
    base.Size = ApplicationBase.Instance.ScreenSize;
    ApplicationBase.Instance.PropertyChanged += HandlePropertyChanged;
}

该属性如下所示:

public virtual Vector2 Size
{
    get
    {
        return _Size;
    }
    set
    {
        Vector2 old = _Size;
        if (SetData(SizeDeclaration, value, ref _Size, Invalidate))
        {
            CompareUpdate(WidthDeclaration, _Size.X, old.X);
            CompareUpdate(HeightDeclaration, _Size.Y, old.Y);
        }
    }
}

好吧,Vector2 是一个结构体,不能为 null.这段代码也可以在桌面上完美运行.我想不出这段代码应该崩溃的任何原因,但它也不会在 iOS 模拟器上,仅在 iOS 设备上(我目前没有设备,所以我无法直接调试它).

Well the Vector2 is a struct and cannot be null. Also this code works perfectly on desktop. I can't think of any reason why this code should crash but it also does not on iOS simulator, only on iOS-device ( I currently have no device so i'm not able to debug it directly ).

我在调用这段代码之前启动了一些任务,但是它们使用自己的数据并且不能与当前数据冲突,即使这样也不应该有任何NullReferenceException.

事实证明,当应该调用 CompareUpdate 方法时会抛出异常.无论如何,我认为非虚拟通用方法不应该有任何问题?

It turns out that the exception is thrown when the CompareUpdate-method should be called. Anyway i thought that non virtual generic methods should not make any issues?

protected Boolean CompareUpdate<T>(DependencyProperty property, T newValue, T oldValue)
{
    if (!Object.Equals(newValue, oldValue))
    {
        ForceUpdate(property, newValue, oldValue);
        return true;
    }
    return false;
}

编辑 2

在更多的测试用例之后,我发现这可能是一个真正的编译器问题.以下测试失败:

Edit 2

After some more test cases i found out that that this might be a real compiler issue. The following test fails:

Log.Info(_Size.X.ToString()); // _Size is still a struct

除此之外:

System.NullReferenceException:未将对象引用设置为对象的实例
在 System.Single.ToString () [0x00000] 在/Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Single.cs:260
在 Pipedream.UI.UIElement.set_Size (Vector2 value) [0x00031] in C:\WORK\00_PROJECTS\16 Pipedream\00_FRAMEWORK\trunk\Pipedream\UI\UIElement.cs:332

System.NullReferenceException: Object reference not set to an instance of an object
at System.Single.ToString () [0x00000] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Single.cs:260
at Pipedream.UI.UIElement.set_Size (Vector2 value) [0x00031] in C:\WORK\00_PROJECTS\16 Pipedream\00_FRAMEWORK\trunk\Pipedream\UI\UIElement.cs:332

如果我将原始代码更改为以下代码也没有错误:

If i change the original code to the following there is also no error:

Vector2 old = _Size;
if (SetData(SizeDeclaration, value, ref _Size, Invalidate))
{
    CompareUpdate(WidthDeclaration, 0f, 0f);
    CompareUpdate(HeightDeclaration, 0f, 0f);
}

当我删除 SetData 方法时也会发生此错误,因此这不可能是错误原因.我已经检查了这个引用,所以堆栈似乎没问题,但是如果我尝试访问 _Sizes 变量 X 并尝试将它打印到控制台 NullReferenceException再次发生.

This error also occurs when i remove the SetData-method, so this can't be the error cause. I've checked the this reference so the stack seems to be ok, but if i try to access the _Sizes variable X and try to print it to the console the NullReferenceException occurs again.

推荐答案

事实证明这存在架构差异错误.Vector2[StructLayout(LayoutKind.Sequential, Pack = 1)] 行导致 Vector2 未对齐,这在某些架构中是非法的.

As it turns out this has an architecture difference bug. The [StructLayout(LayoutKind.Sequential, Pack = 1)] line of the Vector2 causes the Vector2 to be unaliagned which is illegal in some architectures.

暂时删除该行即可解决问题.

Removing the line for now removed the issue.

这篇关于Monotouch 在不可为空的对象上因 NullReferenceException 崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆