【问题标题】:Xamarin.Forms ListView ItemsSource - Async Update NullReferenceExceptionXamarin.Forms ListView ItemsSource - 异步更新 NullReferenceException
【发布时间】:2017-04-12 13:37:12
【问题描述】:

在布局后,我无法在列表视图上更新 ItemsSource。我正在使用对 Web 服务的异步调用来填充表格,如果我在创建包含列表视图的页面之前等待接收数据,它工作正常。但是,当我尝试异步加载列表视图时,我得到一个空引用异常或参数超出范围异常。

-如果我将传入数据添加到新集合中,然后将其分配为 itemsSource,我会得到 ArgumentOutOfRangeException。

-如果我尝试将新项目直接添加到我的 itemsSource 中,我会在插入第一条记录后得到空引用异常。

我已经通过调试器确认没有分配空值,并且看起来异常与过早地被垃圾收集的对象有关 - 我不确定它指的是什么对象。

更新: 该问题仅发生在 iOS 实现上。列表视图完全按照 Android 上的预期加载传入数据。

这是我的列表视图:

public class TransferListView : ListView
{

    public ObservableCollection<TransferCell> transferCells;

    public TransferListView()
    {
        var curData = ESPMobileDS.GetSharedInstance();
        transferCells = new ObservableCollection<TransferCell>();

        ItemTemplate = TransferListView.GetCellTemplate();
        ItemsSource = transferCells;

        RowHeight = 75;
        HorizontalOptions = LayoutOptions.FillAndExpand;
        VerticalOptions = LayoutOptions.FillAndExpand;
        BackgroundColor = ESPResources.Color.SoftBackgroundColorLight2;

        BindingContext = TransferCell.IdentityProperty;

        ItemSelected += async (sender, e) => 
        {
            curData.SelectedTransfer = e.SelectedItem as TransferCell;
            await Navigation.PushAsync(new ItemDetailPage(DetailItemType.Transfer));
        };
    }

    public static DataTemplate GetCellTemplate()
    {
        var cell = new DataTemplate(typeof(TransferCell));
        cell.SetBinding(TransferCell.AccountFromProperty, "AccountFrom");
        cell.SetBinding(TransferCell.AccountToProperty, "AccountTo");
        cell.SetBinding(TransferCell.DateProperty, "Date");
        cell.SetBinding(TransferCell.DescriptionProperty, "Description");
        cell.SetBinding(TransferCell.AmountProperty, "Amount");
        cell.SetBinding(TransferCell.IdentityProperty, "Identity");
        cell.SetBinding(TransferCell.CanDeleteProperty, "CanDelete");
        cell.SetBinding(TransferCell.IsPendingProperty, "IsPending");

        return cell;
    }

    public void ParseAndReceiveServerResponse(string data) {

        var curData = ESPMobileDS.GetSharedInstance();

        var deserializationSettings = new JsonSerializerSettings
        {
            NullValueHandling = NullValueHandling.Ignore,
            MissingMemberHandling = MissingMemberHandling.Ignore
        };

        Dictionary<string, TransferInfoListResponse> transferDict = JsonConvert.DeserializeObject<Dictionary<string, TransferInfoListResponse>>(data, deserializationSettings);

        var transfers = transferDict["d"].Transfers;



        if (transfers != null) {

            Device.BeginInvokeOnMainThread(() => {


                curData.currentPage.RemoveLoadingModal();

                for (int i = 0; i < transfers.Count; i++) {


                    transferCells.Add(new TransferCell
                    {
                        AccountFrom = curData.GetNameForAccountNumber(transfers[i].FromAccount).ToUpper(),
                        AccountTo = curData.GetNameForAccountNumber(transfers[i].ToAccount).ToUpper(),
                        Description = transfers[i].Description,
                        Date = transfers[i].Date,
                        ID = i,
                        Amount = transfers[i].Amount,
                        CanDelete = transfers[i].CanDelete,
                        IsPending = transfers[i].IsPending
                    });



                }

            });
        }

    }
}

这是它所在的页面:

public class TransferPage : ESPMobilePage
{
    BindableBoolean amountEntryVisible;
    CustomEntry amountEntry;
    TransferListView transferListView { set; get; }

    AbsoluteLayout addTransferModal { set; get; }

    Picker fromPicker;
    Picker toPicker;
    Picker amountPicker;


    protected override async void OnAppearing() {
        base.OnAppearing();
        var curData = ESPMobileDS.GetSharedInstance();

        await curData.PostToServer(curData.GetPostDataForResponseType(ResponseType.TransferInfoResponse), ESPResources.WebService.URL.GetTransferListMethod).ContinueWith((transferListResponse) => {

            transferListView.ParseAndReceiveServerResponse(transferListResponse.Result);
        });
    }

    public TransferPage ()
    {
        Title = " ";
        Icon = ESPResources.Image.SystemImage.Empty;
        NavigationPage.SetTitleIcon(this, ESPResources.Image.SystemImage.Empty);

        var curData = ESPMobileDS.GetSharedInstance();
        curData.SetCurrentPage(this);

        amountEntryVisible = new BindableBoolean ();
        amountEntryVisible.ShouldBeVisible = false;


        layout = new AbsoluteLayout () {
            HorizontalOptions = LayoutOptions.FillAndExpand,
            VerticalOptions = LayoutOptions.FillAndExpand
        };

        var addTransferTapRecognizer = new TapGestureRecognizer
        {
            Command = new Command(() => {
                OnAddTransfer();
            }),
            NumberOfTapsRequired = 1
        };

        var addButton = new CachedImage
        {
            Source = ESPResources.Image.SystemImage.AddButton,
            Aspect = Aspect.Fill
        };
        addButton.GestureRecognizers.Add(addTransferTapRecognizer);

        CustomNavigationBar navigationBar = new CustomNavigationBar(ESPResources.Text.Symbol.MenuSymbol, ESPResources.FontFamily.SymbolFont, LayoutGen.BuildMenuTapHandler()); 

        transferListView = new TransferListView();

        var unfinishedLayout = LayoutGen.BuildNewCoreLayout(ESPResources.Text.Title.TransferPage.ToUpper(), transferListView, navigationBar);
        var mainLayout = LayoutGen.AddCoreLayoutButton(addButton, unfinishedLayout);

        AbsoluteLayout.SetLayoutBounds (unfinishedLayout, new Rectangle(0,0,1,1));
        AbsoluteLayout.SetLayoutFlags (unfinishedLayout, AbsoluteLayoutFlags.All);

        layout.Children.Add(mainLayout);
        Content = layout;
    }

这里是来自 NullReferenceException 的堆栈跟踪:

 Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: 
    Unhandled Exception:
    System.NullReferenceException: Object reference not set to an instance of an object
      at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
      at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
      at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
      at ESPMobile.iOS.Application.Main (System.String[] args) [0x00008] in /Users/clarkin/Projects/ewu-larkinc/ESPMobile/iOS/Main.cs:13 
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: Unhandled managed exception:
    Object reference not set to an instance of an object (System.NullReferenceException)
      at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr)
      at UIKit.UIApplication.Main (System.String[] args, System.IntPtr principal, System.IntPtr delegate) [0x00005] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:79 
      at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x00038] in /Users/builder/data/lanes/3969/44931ae8/source/xamarin-macios/src/UIKit/UIApplication.cs:63 
      at ESPMobile.iOS.Application.Main (System.String[] args) [0x00008] in /Users/clarkin/Projects/ewu-larkinc/ESPMobile/iOS/Main.cs:13 
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical: Stacktrace:
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical: 
    Native stacktrace:
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  0   ESPMobileiOS                        0x000000010b21f6bd mono_handle_native_sigsegv + 253
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  1   libsystem_platform.dylib            0x00000001119a3bba _sigtramp + 26
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  2   ???                                 0x000000010b61f99b 0x0 + 4485937563
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  3   libsystem_c.dylib                   0x00000001116fafd7 abort + 129
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  4   ESPMobileiOS                        0x000000010b3c4f0f xamarin_unhandled_exception_handler + 47
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  5   ESPMobileiOS                        0x000000010b21ff8c mono_invoke_unhandled_exception_hook + 92
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  6   ESPMobileiOS                        0x000000010b21ef0f mono_handle_exception_internal + 5119
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  7   ESPMobileiOS                        0x000000010b21db08 mono_handle_exception + 24
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  8   ESPMobileiOS                        0x000000010b19867f mono_amd64_throw_exception + 143
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  9   ???                                 0x000000011dcaa9e7 0x0 + 4794788327
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  10  ESPMobileiOS                        0x000000010b3ca845 xamarin_invoke_trampoline + 7541
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  11  ESPMobileiOS                        0x000000010b3d1cdd xamarin_arch_trampoline + 189
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  12  ESPMobileiOS                        0x000000010b3d3021 xamarin_x86_64_common_trampoline + 110
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  13  UIKit                               0x000000010b80f7b5 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 757
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  14  UIKit                               0x000000010b80fa13 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  15  UIKit                               0x000000010b7e347d -[UITableView _updateVisibleCellsNow:isRecursive:] + 3295
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  16  UIKit                               0x000000010b818d95 -[UITableView _performWithCachedTraitCollection:] + 110
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  17  UIKit                               0x000000010b7ff5ef -[UITableView layoutSubviews] + 222
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  18  UIKit                               0x000000010b766f50 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1237
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  19  QuartzCore                          0x000000010d5bbcc4 -[CALayer layoutSublayers] + 146
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  20  QuartzCore                          0x000000010d5af788 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  21  QuartzCore                          0x000000010d5af606 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  22  QuartzCore                          0x000000010d53d680 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 280
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  23  QuartzCore                          0x000000010d56a767 _ZN2CA11Transaction6commitEv + 475
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  24  QuartzCore                          0x000000010d56b0d7 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 113
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  25  CoreFoundation                      0x000000010ef88e17 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  26  CoreFoundation                      0x000000010ef88d87 __CFRunLoopDoObservers + 391
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  27  CoreFoundation                      0x000000010ef6db9e __CFRunLoopRun + 1198
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  28  CoreFoundation                      0x000000010ef6d494 CFRunLoopRunSpecific + 420
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  29  GraphicsServices                    0x00000001106f5a6f GSEventRunModal + 161
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  30  UIKit                               0x000000010b6a2964 UIApplicationMain + 159
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  31  ???                                 0x000000011f656ca2 0x0 + 4821707938
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical:  32  ???                                 0x000000011f656b30 0x0 + 4821707568
Nov 28 08:26:03 apples-iMac ESPMobileiOS[24684]: critical: 
    =================================================================
    Got a SIGABRT while executing native code. This usually indicates
    a fatal error in the mono runtime or one of the native libraries 
    used by your application.

【问题讨论】:

  • 抛出 NullRef 时是否有可用的堆栈跟踪?这将帮助您追踪它。
  • 好的,我添加了堆栈跟踪 - 但是我在其中找不到任何有用的东西。
  • 你能确认 curData.GetNameForAccountNumber() 没有返回 null 吗?您可以通过将调试器设置为在任何异常上中断来跟踪它
  • @therealjohn 是的,我已经通过调试器确认所有数据都存在(这在我的 android 项目中运行良好)。实际分配 itemsSource 时会引发空引用异常(仅在 iOS 上)。我可以通过重新实例化列表视图来避免异常,但随后什么也没有出现。
  • 在将类似的样本拼凑在一起时,我似乎无法重现这一点。我缺少的主要内容是反序列化和网络访问。你能在bugzilla.xamarin.com 提交一个错误并包含一个测试用例吗?您可以将任何附件标记为私有。我去看看。

标签: listview garbage-collection async-await xamarin.forms itemssource


【解决方案1】:

我似乎记得在 iOS 上更新 ObservableCollections 时存在问题。尝试更换整个东西。例如,在 ParseAndReceiveServerResponse 方法的底部试试这个:

var tempList = new List<TransferCell>();

for (int i = 0; i < transfers.Count; i++) 
{
    tempList.Add(new TransferCell
    {
        AccountFrom = curData.GetNameForAccountNumber(transfers[i].FromAccount).ToUpper(),
        AccountTo = curData.GetNameForAccountNumber(transfers[i].ToAccount).ToUpper(),
        Description = transfers[i].Description,
        Date = transfers[i].Date,
        ID = i,
        Amount = transfers[i].Amount,
        CanDelete = transfers[i].CanDelete,
        IsPending = transfers[i].IsPending
    });
}

ItemsSource = new ObservableCollection<TransferCell>(tempList);

【讨论】:

  • 感谢您的帮助,不幸的是我仍然遇到同样的错误。临时列表已完全填充,如我所料(包含 71 条有效记录),但是当我分配 itemssource 时 - 应用程序输出窗口仅显示在引发空引用异常之前布置了 1 个 TransferCell。
  • 第二个TransferCell是否有空值?
  • 不,没有 - 我使用了一些额外的打印语句来确认所有传入的传输对象都已完全填充。
【解决方案2】:

CachingStrategy="RecycleElement" 解决了我的问题。

您也可以通过此解决方法:https://bugzilla.xamarin.com/59/59813/bug.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 2015-11-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多