尝试在Xamarin.iOS中更新XIB的子视图时抛出NullReferenceException

时间:2014-10-15 16:55:26

标签: ios xamarin.ios interface-builder xamarin-studio

我正在测试Xamarin Studio并使用Xamarin.iOS进行部署。我刚刚开始了解iOS应用的行为以及如何使用其工具。

我已经掌握了使用Xcode Interface Builder(IB)创建自定义视图的基础知识,以及如何在我在Xamarin Studio项目中创建的故事板上显示它们。

现在我要做的是根据用户与其中其他组件的互动来更新自定义视图的内容。

例如,我有一个自定义视图,其中包含表视图和图像视图。表格中的每一行代表一个图像文件路径,当选择一行时,相应的图像应显示在图像视图中。

我实现了自己的UITableViewSource类,我按如下方式覆盖RowSelected方法:

    public override void RowSelected (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
        var index = indexPath.Row;
        var item = tableItems [index];

        selectedFilePath = item;
        var array = GetFilePathArray (item);
        selectedFileName = GetFileName (array);
        // I should be using an interface but this is only a test
        ((SavedPhotosView)tableView.Superview).SetSelectedFile (selectedFileName, selectedFilePath);
    }

    protected string[] GetFilePathArray(string path){
        string[] separators = { "/" };
        return path.Split (separators, StringSplitOptions.RemoveEmptyEntries);
    }

    protected string GetFileName(string[] pathArray){
        var arrayLength = pathArray.Length;
        return pathArray [arrayLength - 1];
    }

SavedPhotosView是我创建的用于将SavedPhotosView.xib文件连接到我的项目的类,我使用的实现如下:

[Register("SavedPhotosView")]
public partial class SavedPhotosView : UIView
{
    public SavedPhotosView(IntPtr h): base(h){

    }

    public SavedPhotosView(){

        var arr = NSBundle.MainBundle.LoadNib ("SavedPhotosView", this, null);
        var v = Runtime.GetNSObject (arr.ValueAt (0)) as UIView;
        v.Frame = new RectangleF (0, 0, Frame.Width, Frame.Height);

        // For some reason I can register the class for the cell here without receiving a null exception
        SavedPhotosTableView.RegisterClassForCellReuse (typeof(UITableViewCell), (NSString)SavedPhotosTableViewSource.cellIdentifier);

        AddSubview (v);
    }
    // Method used to update the source of the table view, null exception isn't thrown here
    public void SetSource(UITableViewSource source){
        InvokeOnMainThread (delegate {

            SavedPhotosTableView.Source = source;
            SavedPhotosTableView.ReloadData ();
        });
    }
    // Method that receives the file name and file path for the image to be displayed
    public void SetSelectedFile(string filename, string filepath){
        UIImage selectedImage = UIImage.FromFile (filepath);
        // Null reference exception is thrown here, also if I try to update something on the table view here I get a null reference exception too
        InvokeOnMainThread (delegate {
            SelectedSaveImageView.Image = selectedImage;
        });
    }
}

我不明白导致此异常的原因,当我更新表格视图的源对象时,我不会遇到任何异常,但在我的其他方法中,我的表视图或图像视图都不能完全被引用。

我在IB中为我的表视图和图像视图创建了出口,所以我希望能够从我的C#类中引用它们没有问题。

我的实施在这里错了吗?如何在我的自定义视图中引用其他元素而不必担心会抛出这种异常?

编辑1

我注意到当我调用我的SetSource方法时,我正在从我的ViewController调用我的自定义视图。

这意味着我可以访问这些插座,但前提是从我的控制器内部调用该方法。

不幸的是,当我尝试将ViewController的一个实例传递给SavedPhotosView(C#类,代表用我的Xamarin.iOS代码绑定xib文件据我所知),我调试了应用程序,实际上参考是在我创建SavedPhotosView实例时正确传递,但是当我的表视图源处理click事件并尝试访问此View Controller实例时,引用为null。

为什么我的引用无效?

我在SavedPhotosView中尝试使用静态引用我的ViewController,但我不喜欢这种解决方法。它有效,但这不是我想要的方法。

我怎样才能获得这种解决方法?或者这是唯一的方法吗?

堆栈追踪:

System.NullReferenceException: Object reference not set to an instance of an object
  at TestCustomViewsiOS.UI.Views.SavedPhotosView+<SetSelectedFile>c__AnonStorey1.<>m__0 () [0x00012] in /Users/xxxxxxxxx/Projects/TestCustomViewsiOS/TestCustomViewsiOS/UI/Views/SavedPhotosView.cs:41
  at MonoTouch.Foundation.NSActionDispatcher.Apply () [0x00000] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSAction.cs:56
  at at (wrapper managed-to-native) MonoTouch.ObjCRuntime.Messaging:void_objc_msgSend_IntPtr_IntPtr_bool (intptr,intptr,intptr,intptr,bool)
  at MonoTouch.Foundation.NSObject.InvokeOnMainThread (MonoTouch.Foundation.NSAction action) [0x00007] in /Developer/MonoTouch/Source/maccore/src/Foundation/NSObject2.cs:506
  at TestCustomViewsiOS.UI.Views.SavedPhotosView.SetSelectedFile (System.String filename, System.String filepath) [0x00027] in /Users/xxxxxxxxxx/Projects/TestCustomViewsiOS/TestCustomViewsiOS/UI/Views/SavedPhotosView.cs:40
  at TestCustomViewsiOS.ApplicationLayer.DataSource.SavedPhotosTableViewSource.RowSelected (MonoTouch.UIKit.UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath) [0x00048] in /Users/xxxxxxxxxx/Projects/TestCustomViewsiOS/TestCustomViewsiOS/Application/DataSource/SavedPhotosTableViewSource.cs:64
  at at (wrapper managed-to-native) MonoTouch.UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:62
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:46
  at TestCustomViewsiOS.Application.Main (System.String[] args) [0x00008] in /Users/xxxxxxxxxxxx/Projects/TestCustomViewsiOS/TestCustomViewsiOS/Main.cs:17

1 个答案:

答案 0 :(得分:0)

不确定您的情况,但是当我忘记将Interface Builder中的对象与文件对象中的参考点连接时,我经常会遇到此错误。