Monotouch在非可空对象上与NullReferenceException崩溃

时间:2013-04-24 23:17:53

标签: c# xamarin.ios xamarin

这是崩溃日志(简称):

  

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

实际上构造函数的代码如下所示:

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设备上(我目前没有设备,所以我无法直接调试)。

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

修改

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

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

编辑2

经过一些测试用例后,我发现这可能是一个真正的编译器问题。以下测试失败:

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

有这个例外:

  

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

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

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

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

1 个答案:

答案 0 :(得分:0)

事实证明这有一个架构差异错误。 [StructLayout(LayoutKind.Sequential, Pack = 1)]的{​​{1}}行导致Vector2不合法,这在某些架构中是非法的。

现在删除该行已删除该问题。