解决“'NSUnknownKeyException',原因:这个类不是密钥X的编码兼容的键值”exception

我遇到了与本次提交中确定的完全相同的问题: MvvmCross / Xamarin“这个类不是关键值编码,

这个问题源于尝试在IOS CollectionView中使用MVVMCross数据绑定

那篇文章被封闭并被标记为重复,但是我不认为是这样。 作为解决scheme链接的文章提供了使用XCode作为开发环境时的解决方法。 上面链接的问题中描述的我的场景和场景是在Windows上使用Visual Studio与Xamarin一起构build的。 使用Visual Studio,XIB编辑器和布线sockets的做法各不相同。

我一直试图解决这个问题好几天了,而且还没有弄清楚什么。 我希望有人在Windows Visual Studio中看到这个解决scheme,他们可以共享。

(我很抱歉,我是新的,所以我不能在原来的post中作为评论)。

错误的堆栈跟踪如下

Foundation.MonoTouchException: Objective-C exception thrown. Name: NSUnknownKeyException Reason: [<NSObject 0x7c4eb9a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key view. Native stack trace: 0 CoreFoundation 0x00928494 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x08fa3e02 objc_exception_throw + 50 2 CoreFoundation 0x009280b1 -[NSException raise] + 17 3 Foundation 0x014477f8 -[NSObject(NSKeyValueCoding) setValue:forUndefinedKey:] + 282 4 Foundation 0x013a1e6a _NSSetUsingKeyValueSetter + 115 5 Foundation 0x013a1def -[NSObject(NSKeyValueCoding) setValue:forKey:] + 295 6 Foundation 0x013d654b -[NSObject(NSKeyValueCoding) setValue:forKeyPath:] + 384 7 UIKit 0x03bc8a62 -[UIRuntimeOutletConnection connect] + 132 8 libobjc.A.dylib 0x08fb800c -[NSObject performSelector:] + 62 9 CoreFoundation 0x00851131 -[NSArray makeObjectsPerformSelector:] + 273 10 UIKit 0x03bc70fc -[UINib instantiateWithOwner:options:] + 2102 11 UIKit 0x041205ec -[UICollectionView _dequeueReusableViewOfKind:withIdentifier:forIndexPath:viewCategory:] + 750 12 UIKit 0x04120f35 -[UICollectionView dequeueReusableCellWithReuseIdentifier:forIndexPath:] + 194 13 ??? 0x1b909f9c 0x0 + 462462876 14 ??? 0x1be1b820 0x0 + 467777568 15 ??? 0x1be1b633 0x0 + 467777075 16 ??? 0x1be1adf6 0x0 + 467774966 17 ??? 0x1be1b08d 0x0 + 467775629 18 CompanionForSpotifyiOS 0x001bb2a1 mono_jit_runtime_invoke + 705 19 CompanionForSpotifyiOS 0x00276fef mono_runtime_invoke + 127 20 CompanionForSpotifyiOS 0x0034bb77 xamarin_trampoline + 5559 21 UIKit 0x0410d5ee -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:] + 448 22 UIKit 0x0410d2ff -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 65 23 UIKit 0x04111761 -[UICollectionView _updateVisibleCellsNow:] + 6023 24 UIKit 0x041167df -[UICollectionView layoutSubviews] + 254 25 UIKit 0x038543d4 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 810 26 libobjc.A.dylib 0x08fb8059 -[NSObject performSelector:withObject:] + 70 27 QuartzCore 0x0b5d8096 -[CALayer layoutSublayers] + 144 28 QuartzCore 0x0b5cb8b6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 388 29 QuartzCore 0x0b5cb71a _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26 30 QuartzCore 0x0b5bdee7 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 317 31 QuartzCore 0x0b5f2847 _ZN2CA11Transaction6commitEv + 561 32 QuartzCore 0x0b5f3108 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92 33 CoreFoundation 0x0083a75e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 34 CoreFoundation 0x0083a6be __CFRunLoopDoObservers + 398 

ViewModel代码在这里

 public partial class AlbumCell : MvxCollectionViewCell { public static readonly UINib Nib = UINib.FromName("AlbumCell", NSBundle.MainBundle); public static readonly NSString Key = new NSString("AlbumCell"); public AlbumCell(IntPtr handle) : base(string.Empty, handle) { this.DelayBind(() => { var set = this.CreateBindingSet<AlbumCell, Album>(); set.Bind(artistNameLabel).To(album => album.ArtistName); set.Apply(); }); } public static AlbumCell Create() { return (AlbumCell)Nib.Instantiate(null, null)[0]; } } 

这是生成的视图模型的组成部分[Register(“AlbumCell”)]部分类AlbumCell {[Outlet] [GeneratedCode(“iOS Designer”,“1.0”)] UILabel artistNameLabel {get; 组; }

  void ReleaseDesignerOutlets () { if (artistNameLabel != null) { artistNameLabel.Dispose (); artistNameLabel = null; } } } 

最后,这是非常基本的XIB – 它只有一个标签

 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/> </dependencies> <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AlbumCell"> <connections> <outlet property="view" destination="2" id="RRd-Eg-VrN"/> </connections> </placeholder> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <view contentMode="scaleToFill" id="2"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <subviews> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" fixedFrame="YES" text="Label" lineBreakMode="tailTruncation" minimumFontSize="10" translatesAutoresizingMaskIntoConstraints="NO" id="5"> <rect key="frame" x="279" y="95" width="42" height="21"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> </view> </objects> </document> 

下面是从父级ViewController创build单元对象实例的代码

 public partial class NewReleasesView : MvxCollectionViewController { public NewReleasesView() : base(new UIKit.UICollectionViewFlowLayout() { ItemSize = new CoreGraphics.CGSize(250,200), ScrollDirection = UICollectionViewScrollDirection.Vertical }) { } public override void ViewDidLoad() { base.ViewDidLoad(); CollectionView.RegisterNibForCell(AlbumCell.Nib, AlbumCell.Key); var source = new MvxCollectionViewSource(CollectionView, AlbumCell.Key); CollectionView.Source = source; var set = this.CreateBindingSet<NewReleasesView, NewReleasesViewModel>(); set.Bind(source).To(vm => vm.NewReleases); set.Apply(); CollectionView.ReloadData(); var viewModel = this.ViewModel as IMvxViewModel; viewModel.Start(); } } 

看起来像Visual Studio正在把网点放在错误的位置。 看下面我input“Outlet在这里”。 这是UI标签生成的地方。 我手动删除它,然后进入Visual Studio中的XIB编辑器,并在devise器中重新添加sockets名称。 就在这个时候,它把它放在了正确的地方,我贴上了“当它应该在这里”。

我不确定是什么原因导致了这个行为,但是这个工作绝对是个窍门。 感谢所有帮助我的人。

 <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AlbumCell"> <connections> ***OUTLET WAS HERE*** </connections> </placeholder> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <view contentMode="scaleToFill" id="1" customClass="AlbumCell"> <rect key="frame" x="0.0" y="0.0" width="250" height="250"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <color key="backgroundColor" customColorSpace="calibratedWhite" colorSpace="calibratedWhite" white="0" alpha="1"/> <subviews> <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" text="Label" lineBreakMode="tailTruncation" minimumFontSize="10" id="4" translatesAutoresizingMaskIntoConstraints="NO" fixedFrame="YES" customClass="UILabel"> <rect key="frame" x="53" y="20" width="177" height="21"/> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" colorSpace="calibratedWhite" white="1" alpha="1"/> <nil key="highlightedColor"/> </label> </subviews> <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> <size key="freeformSize" width="600" height="600"/> <connections> ***WHEN IT SHOULD HAVE BEEN HERE*** <outlet property="artistname" destination="4" id="name-outlet-4"/> </connections> </view> </objects> 

感谢@ Paulw11q的指导,我发现了这个问题。 我不得不与RegisterNibForCell一起调用下面的行,以便MVVMCross知道它需要创build的对象的types。 我看到的所有MVVMCross样本都缺less这条线。 谢谢保罗带领我走这条路!

CollectionView.RegisterClassForCell(typeof(AlbumCell),AlbumCell.Key);