简体   繁体   English

麻烦xamarin.ios / monotouch,mvvmcross和链接

[英]Trouble with xamarin.ios/monotouch , mvvmcross and linking

I have an irritating issue, if I use Link SDK Assemblies only in xamarin studio I get an exception, if I use dont link the exception is not happening. 我有一个恼人的问题,如果我只在xamarin工作室使用链接SDK程序集我得到一个例外,如果我使用不链接异常没有发生。 I have located the issue to be part of an third party dll i am using(api for a video streaming service). 我已经将问题定位为我正在使用的第三方dll的一部分(api用于视频流服务)。 I believe the linker is stripping some of the methods used by this dll. 我相信链接器正在剥离这个dll使用的一些方法。 Is it possible skip link of some libraries and is it possible to see which from this stacktrace. 是否可以跳过某些库的链接,是否可以从这个堆栈跟踪中查看哪些库。

    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 

Any help is appreciated. 任何帮助表示赞赏。

UPDATE: As suggested by stuart (thanks stuart) I have added an LinkerPleaseInclude file with the following: But it still get an exception. 更新:正如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();
        }

    }

My thought was that it had to be something related to the stacktrace 我的想法是它必须是与堆栈跟踪相关的东西

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

But it seems not to do the trick - any pointers to find what is stripped out? 但它似乎没有做到这一点 - 任何指针找到被剥离的东西?

Is it possible skip link of some libraries 是否可以跳过某些库的链接

Yes. 是。 You can isolate the issue (and be 100% sure of its origin) to your 3rd party by using the --linkskip=ASSEMBLY option (in Additional mtouch arguments in your project's options). 您可以使用--linkskip=ASSEMBLY选项(在项目选项中的其他mtouch参数中)将问题(并且100%确定其来源)隔离到第三方。 It can be used as a release workaround too (but you better find a more precise solution to get the full benefits from the linker). 它也可以用作发布解决方法(但您最好找到一个更精确的解决方案,以便从链接器中获得全部好处)。

Eg --linkskip=mscorlib would skip mscorlib.dll (ie no file extension) 例如--linkskip=mscorlib会跳过mscorlib.dll(即没有文件扩展名)

is it possible to see which from this stacktrace ? 是否有可能从这个堆栈跟踪中看到哪个?

Not quite. 不完全的。 The issue is not with System.Delegate.Combine . 问题不在于System.Delegate.Combine Since it's named in the stack trace then you know it's not removed by the linker. 由于它在堆栈跟踪中命名,因此您知道它不会被链接器删除。

OTOH one of it's argument (a delegate) is likely removed. OTOH其中一个论点(代表)很可能被删除。 That can (most likely) happen if it was created using reflection (since the linker use static analysis). 如果它是使用反射创建的(因为链接器使用静态分析),那么(很可能)会发生这种情况。 You can use the stack trace to see what (type) should have been used in the Combine call and work backward from there, eg to find how it was created. 您可以使用堆栈跟踪来查看在Combine调用中应该使用的内容(类型)并从那里向后工作,例如查找它是如何创建的。

Once you find it you'll want the linker to keep it. 一旦找到它,您将希望链接器保留它。 You can do so by adding extra, unneeded code (like @Stuart suggested). 您可以通过添加额外的,不需要的代码(如@Stuart建议)来实现。 My own suggestions are to: 我自己的建议是:

  • use [Preserve] attributes when you have the source code; 拥有源代码时使用[Preserve]属性;

  • use an XML file (and --xml=file ) when you do not have the source code; 如果没有源代码,请使用XML文件 (和--xml=file );

Can't assist with the unnamed video api. 无法协助未命名的视频API。

But to work around Mvvmcross linking issues: 但要解决Mvvmcross链接问题:

  • You'll need to work out what page/viewcontroller the linker error is happening on. 您需要确定链接器错误发生在哪个页面/视图控制器上。

  • Then you simply need to add a LinkerPleaseInclude.cs file to trick the linker into not removing whatever symbol it is stripping 然后你只需要添加一个LinkerPleaseInclude.cs文件来欺骗链接器不删除它正在剥离的任何符号

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

I was not able to find what was missing, when the linker was doing its job. 当链接器正在执行其工作时,我无法找到遗漏的内容。

However I found that during one binding, the video api was doing a synchrony restsharp call which made the binding wait till done and this seemed to cause the problem. 但是我发现在一次绑定期间,视频api正在进行同步的restsharp调用,这使得绑定等待完成,这似乎导致了问题。 If I changed the workflow and started a asynchrony restsharp call, which then starts the binding when done, it all worked as a charm. 如果我更改了工作流程并启动了异步restsharp调用,然后在完成时启动绑定,那么这一切都可以作为一个魅力。

Thank you vey much for your help. 谢谢你的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM