【发布时间】:2020-05-12 17:38:08
【问题描述】:
我有一个 BLE 扫描应用程序,它使用 this plugin 持续扫描附近的设备。发现设备后,会将它们添加到 ObservableRangeCollection(来自 James Montemagno 的 MvvmHelpers)。如果设备已经在列表中并且它的一些数据(例如,RSSI 强度)发生了变化,则使用ReplaceRange() 更新集合。如果设备在列表中的时间过长而没有更新,则将其从集合中删除。
这在 Android 上运行顺利,但在 iOS 上会引发 ArgumentOutOfRange 异常。异常并不总是同时出现,但如果我让应用程序运行足够长的时间,它最终会抛出。不幸的是,堆栈跟踪没有指向我的代码中的任何内容,因此很难判断这是否与 BLE 插件、ObservableRangeCollection 插件甚至 Xamarin.Forms 相关。
这是异常消息和堆栈跟踪:
{System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.Parameter name: index
at Xamarin.Forms.ListProxy.get_Item (System.Int32 index) [0x0000b] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:129
at Xamarin.Forms.ListProxy.System.Collections.IList.get_Item (System.Int32 index) [0x00000] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:443
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].get_Item (System.Int32 index) [0x00008] in <7d3a3d515f644268b15520ab8aaf1bfc>:0
at Xamarin.Forms.Platform.iOS.ListViewRenderer+ListViewDataSource.GetCellForPath (Foundation.NSIndexPath indexPath) [0x00007] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:1327
at Xamarin.Forms.Platform.iOS.ListViewRenderer+ListViewDataSource.GetCell (UIKit.UITableView tableView, Foundation.NSIndexPath indexPath) [0x00021] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:1036
at (wrapper managed-to-native) ObjCRuntime.Messaging.void_objc_msgSend(intptr,intptr)
at UIKit.UITableView.EndUpdates () [0x0000d] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UITableView.g.cs:294
at Xamarin.Forms.Platform.iOS.ListViewRenderer+<>c__DisplayClass52_0.<DeleteRows>b__0 () [0x00048] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:599
at Xamarin.Forms.Platform.iOS.ListViewRenderer.DeleteRows (System.Int32 oldStartingIndex, System.Int32 oldItemsCount, System.Int32 section) [0x00046] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:603
at Xamarin.Forms.Platform.iOS.ListViewRenderer.UpdateItems (System.Collections.Specialized.NotifyCollectionChangedEventArgs e, System.Int32 section, System.Boolean resetWhenGrouped) [0x00119] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:542
at Xamarin.Forms.Platform.iOS.ListViewRenderer.OnCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x00000] in D:\a\1\s\Xamarin.Forms.Platform.iOS\Renderers\ListViewRenderer.cs:332
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000a] in <7d3a3d515f644268b15520ab8aaf1bfc>:0
at Xamarin.Forms.Internals.TemplatedItemsList`2[TView,TItem].OnProxyCollectionChanged (System.Object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0045f] in <7d3a3d515f644268b15520ab8aaf1bfc>:0
at Xamarin.Forms.ListProxy.OnCollectionChanged (System.Collections.Specialized.NotifyCollectionChangedEventArgs e) [0x0000a] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:232
at (wrapper other) System.Object.gsharedvt_out_sig(object&,intptr)
at Xamarin.Forms.ListProxy+<>c__DisplayClass34_0.<OnCollectionChanged>b__0 () [0x00018] in D:\a\1\s\Xamarin.Forms.Core\ListProxy.cs:208
at (wrapper other) System.Object.__interp_lmf_mono_interp_entry_from_trampoline(intptr,intptr)
at Foundation.NSAsyncActionDispatcher.Apply () [0x00000] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/Foundation/NSAction.cs:152
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 /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:86
at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0000e] in /Library/Frameworks/Xamarin.iOS.framework/Versions/13.16.0.13/src/Xamarin.iOS/UIKit/UIApplication.cs:65
at SDA.iOS.Application.Main (System.String[] args) [0x00001] in C:\Users\shodg\SDA\SDA\SDA.iOS\Main.cs:12
这是视图模型中用于从 ObservableRangeCollection 添加/更新/删除设备的相关代码:
public ObservableRangeCollection<DeviceListItemViewModel> Devices { get; set; } = new ObservableRangeCollection<DeviceListItemViewModel>();
private void OnDeviceAdded(BleDevice device)
{
Devices.Add(new DeviceListItemViewModel(device));
}
private void OnDeviceUpdated(BleDevice device)
{
Devices.ReplaceRange(Devices.OrderByDescending(x => x.Rssi).ToList());
}
private void OnDeviceExpired(BleDevice device)
{
var vm = Devices.FirstOrDefault(d => d.Id == device.Id);
Devices.Remove(vm);
}
似乎异常与 iOS 上的 ListView 更新有关,我在 problems with ObservableCollections in Xamarin.iOS 上看到了一些线程,但我无法确定这个问题是出在 Montemagno 插件还是其他地方,以及是什么最好的前进道路是。
欢迎任何见解!
【问题讨论】:
-
删除设备时似乎发生了异常。您可以自行调试以查看删除设备时发生的情况。到目前为止,您分享的代码看起来不错。
标签: c# xamarin xamarin.ios observablecollection ios-bluetooth