5

我有一个恼人的问题,如果我只在 xamarin Studio 中使用 Link SDK Assemblies,我会得到一个异常,如果我使用不链接异常不会发生。我已将问题定位为我正在使用的第三方 dll 的一部分(用于视频流服务的 api)。我相信链接器正在剥离这个 dll 使用的一些方法。是否可以跳过某些库的链接,是否可以从此堆栈跟踪中查看哪个。

    2013-05-08 14:40:54.688 AppsfabrikkenTouch[5662:907] mvx: Diagnostic:  18,23 Exception masked NullReferenceException: Object reference not set to an instance of an object
      at System.Delegate.Combine (System.Delegate a, System.Delegate b) [0x00018] in /Developer/MonoTouch/Source/mono/mcs/class/corlib/System/Delegate.cs:473 
  at Cirrious.MvvmCross.ViewModels.MvxNotifyPropertyChanged.add_PropertyChanged (System.ComponentModel.PropertyChangedEventHandler value) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Source.MvxBasePropertyInfoSourceBinding..ctor (System.Object source, System.String propertyName) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Source.MvxPropertyInfoSourceBinding..ctor (System.Object source, System.String propertyName) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Source.Construction.MvxSourceBindingFactory.CreateBinding (System.Object source, IEnumerable`1 childPropertyNames) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Bindings.Source.Construction.MvxSourceBindingFactory.CreateBinding (System.Object source, System.String combinedPropertyName) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Binders.MvxFullBinding.CreateSourceBinding (System.Object source) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Binders.MvxFullBinding..ctor (Cirrious.MvvmCross.Binding.Interfaces.MvxBindingRequest bindingRequest) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Binders.MvxFromTextBinder.BindSingle (Cirrious.MvvmCross.Binding.Interfaces.MvxBindingRequest bindingRequest) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Binders.MvxFromTextBinder+<>c__DisplayClass1.<Bind>b__0 (Cirrious.MvvmCross.Binding.Interfaces.MvxBindingDescription description) [0x00000] in <filename unknown>:0 
  at System.Linq.Enumerable+<CreateSelectIterator>c__Iterator1D`2[Cirrious.MvvmCross.Binding.Interfaces.MvxBindingDescription,Cirrious.MvvmCross.Binding.Interfaces.IMvxUpdateableBinding].MoveNext () [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.List`1[Cirrious.MvvmCross.Binding.Interfaces.IMvxUpdateableBinding].AddEnumerable (IEnumerable`1 enumerable) [0x00000] in <filename unknown>:0 
  at System.Collections.Generic.List`1[Cirrious.MvvmCross.Binding.Interfaces.IMvxUpdateableBinding].AddRange (IEnumerable`1 collection) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Touch.ExtensionMethods.MvxBindingTouchExtensions.AddBindings (IMvxBindingTouchView view, IEnumerable`1 bindings) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Touch.ExtensionMethods.MvxBindingTouchExtensions.AddBindings (IMvxBindingTouchView view, System.Object source, System.Object target, System.String bindingText) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Touch.ExtensionMethods.MvxBindingTouchExtensions.AddBindings (IMvxBindingTouchView view, System.Object source, IDictionary`2 bindingMap) [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Binding.Touch.ExtensionMethods.MvxBindingTouchExtensions.AddBindings (IMvxBindingTouchView view, IDictionary`2 bindingMap) [0x00000] in <filename unknown>:0 
  at CmsApp.Touch.TabTextView.ViewDidLoad () [0x00074] in /Volumes/2end HDD/Dropbox/AppProjects/Appsfabrikken/CmsApp.Touch/Views/UmbracoViews/TabTextView.cs:45 
  at MonoTouch.UIKit.UINavigationController.PushViewController (MonoTouch.UIKit.UIViewController viewController, Boolean animated) [0x00019] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UINavigationController.g.cs:178 
  at CmsApp.Touch.AppPhonePresenter.Show (IMvxTouchView view) [0x0007b] in /Volumes/2end HDD/Dropbox/AppProjects/Appsfabrikken/CmsApp.Touch/AppPhonePresenter.cs:62 
  at Cirrious.MvvmCross.Touch.Views.Presenters.MvxTouchViewPresenter.Show (Cirrious.MvvmCross.Views.MvxShowViewModelRequest request) [0x00000] in <filename unknown>:0 
  at CmsApp.Touch.AppPhonePresenter.Show (Cirrious.MvvmCross.Views.MvxShowViewModelRequest request) [0x00000] in /Volumes/2end HDD/Dropbox/AppProjects/Appsfabrikken/CmsApp.Touch/AppPhonePresenter.cs:37 
  at Cirrious.MvvmCross.Touch.Views.MvxTouchViewDispatcher+<>c__DisplayClass1.<RequestNavigate>b__0 () [0x00000] in <filename unknown>:0 
  at Cirrious.MvvmCross.Touch.Views.MvxTouchUIThreadDispatcher+<>c__DisplayClass1.<InvokeOrBeginInvoke>b__0 () [0x00000] in <filename unknown>:0 

任何帮助表示赞赏。

更新:根据 stuart 的建议(感谢 stuart),我添加了一个包含以下内容的 LinkerPleaseInclude 文件:但它仍然出现异常。

class LinkerIncludePlease
    {
        private void DelegateCombine(Delegate a, Delegate b)
        {
            var d = Delegate.Combine(a,b);
        }

        private void DelegateCombine(params Delegate[] delegates)
        {
            var d = Delegate.Combine(delegates);
        }

        private void DelegateCombine()
        {
            var d = Delegate.Combine();
        }

    }

我的想法是它必须与堆栈跟踪有关

Exception masked NullReferenceException: Object reference not set to an instance of an object
          at System.Delegate.Combine (System.Delegate a, System.Delegate b) [0x00018] 

但它似乎没有起到作用 - 找到什么被剥离的任何指针?

4

3 回答 3

6

是否可以跳过某些库的链接

是的。您可以使用该--linkskip=ASSEMBLY选项(在项目选项中的Additional mtouch arguments中)将问题(并 100% 确定其来源)隔离给您的第 3 方。它也可以用作发布解决方法(但您最好找到更精确的解决方案以从链接器中获得全部好处)。

例如--linkskip=mscorlib会跳过 mscorlib.dll(即没有文件扩展名)

是否可以从这个堆栈跟踪中看到哪个?

不完全的。问题不在于System.Delegate.Combine. 由于它是在堆栈跟踪中命名的,因此您知道它没有被链接器删除。

OTOH 的一个论点(代表)可能已被删除。如果它是使用反射创建的(因为链接器使用静态分析),这可能(很可能)发生。您可以使用堆栈跟踪来查看调用中应该使用什么(类型)Combine并从那里向后工作,例如查找它是如何创建的。

找到它后,您会希望链接器保留它。你可以通过添加额外的、不需要的代码来做到这一点(如@Stuart 建议的)。我自己的建议是:

  • 拥有源代码时使用[Preserve]属性;

  • 没有源代码时使用XML 文件(和);--xml=file

于 2013-05-08T16:40:04.710 回答
4

无法协助未命名的视频 api。

但是要解决 Mvvmcross 链接问题:

  • 您需要确定链接器错误发生在哪个页面/视图控制器上。

  • 然后你只需要添加一个 LinkerPleaseInclude.cs 文件来欺骗链接器不删除它正在剥离的任何符号

这是一个例子:https ://github.com/MvvmCross/MvvmCross-Tutorials/blob/master/DailyDilbert/DailyDilbert.Touch/LinkerPleaseInclude.cs

于 2013-05-08T13:25:05.037 回答
1

当链接器正在执行其工作时,我无法找到丢失的内容。

但是我发现在一次绑定期间,视频 api 正在执行同步 restsharp 调用,这使得绑定等到完成,这似乎导致了问题。如果我更改了工作流程并启动了一个异步 restsharp 调用,然后在完成后启动绑定,这一切都像一个魅力。

非常感谢您的帮助。

于 2013-05-19T04:54:51.680 回答