Issues with Bindings: Calling base method on binding class calls override method. Leads to infinite recursion

守給你的承諾、 提交于 2020-01-11 14:06:22

问题


I'm working on a MonoTouch project that uses Cordova. I created a binding for Cordova (based on the one created by Scott Blomquist).

I have been able to instantiate the classes fairly well without fail. When I try to extend them however, I run into issues. For example, if I merely try extend the CDVViewController, without even overriding anything, when we get to the code that instantiates this extended class, the system quietly exits with no error messages, and the following exit lines.

The program 'Mono' has exited with code 0 (0x0).
The program '[5600] ***.vshost.exe: Managed (v4.0.30319)' has exited with code -1 (0xffffffff).

Here is the class I'm trying to instantiate

public class WebViewController : CDVViewController
{
}

And here's the binding behind it

[BaseType (typeof (UIViewController))]
interface CDVViewController {
    [Export ("webView")]
    UIWebView WebView { get; set; }

    [Export ("pluginObjects")]
    NSMutableDictionary PluginObjects { get; }

    [Export ("pluginsMap")]
    NSDictionary PluginsMap { get; }

    [Export ("settings")]
    NSDictionary Settings { get; }

    [Export ("whitelist")]
    CDVWhitelist Whitelist { get; }

    [Export ("loadFromString")]
    bool LoadFromString { get; }

    [Export ("useSplashScreen")]
    bool UseSplashScreen { get; set; }

    [Export ("activityView")]
    UIActivityIndicatorView ActivityView { get; }

    [Export ("imageView")]
    UIImageView ImageView { get; }

    [Export ("wwwFolderName")]
    string WwwFolderName { get; set; }

    [Export ("startPage")]
    string StartPage { get; set; }

    [Export ("commandQueue")]
    NSObject CommandQueue { get; set; }

    [Export ("commandDelegate")]
    NSObject CommandDelegate { get; set; }

    [Export ("userAgent")]
    string UserAgent { get; }

    [Export ("printMultitaskingInfo")]
    void PrintMultitaskingInfo ();

    [Export ("createGapView")]
    void CreateGapView ();

    [Export ("newCordovaViewWithFrame:")]
    UIWebView NewCordovaView(RectangleF bounds);

    [Export ("javascriptAlert:")]
    void JavascriptAlert (string text);

    [Export ("appURLScheme")]
    string AppUrlScheme ();

    [Export ("parseInterfaceOrientations:")]
    NSArray ParseInterfaceOrientations (NSArray orientations);

    [Export ("supportsOrientation:")]
    bool SupportsOrientation (UIInterfaceOrientation orientations);

    [Export ("getCommandInstance:")]
    NSObject GetCommandInstance (string pluginName);

    [Export ("registerPlugin:withClassName:")]
    void RegisterPluginWithClassName (CDVPlugin plugin, string className);

    [Export ("URLisAllowed:")]
    bool UrlIsAllowed (NSUrl url);

    [Static] [Export ("getBundlePlist:")]
    NSDictionary GetBundlePlist (string plistName);

    [Static] [Export ("applicationDocumentsDirectory")]
    string ApplicationDocumentsDirectory ();

    // The following methods and properties come from UIWebViewDelegate, but we can't do multiple inheritance
    [Export ("webView:shouldStartLoadWithRequest:navigationType:")]
    bool ShouldStartLoad (UIWebView webView, NSUrlRequest request, UIWebViewNavigationType navigationType);
}

The CDVViewController.h that I build the binding for is available here

Any help that anyone can offer would be greatly appreciated.

Update #1 This appears to have been caused by a segmentation fault. For anyone else experiencing this, if you go onto the Mac and check the log, you will likely find the same. You can do this by opening the terminal, and typing in tail -f /var/log/system.log as apparently this is where the logs for the simulator go.

In my log, I found the following. *** is used for redacting the application name.

Mar 28 16:51:16 macmini1 com.apple.launchd.peruser.55385368[409] (UIKitApplication:com.***.***[0x5ef3][14219]): Job appears to have crashed: Segmentation fault: 11
Mar 28 16:51:16 macmini1 SpringBoard[516]: Application '***' exited abnormally with signal 11: Segmentation fault: 11
Mar 28 16:51:16 macmini1 ReportCrash[14132]: Saved crash report for ***[14219] version ??? (???) to /Users/jstarke/Library/Logs/DiagnosticReports/***_2013-03-28-165116_macmini1.crash
Mar 28 16:51:16 macmini1 ReportCrash[14132]: Removing excessive log: file://localhost/Users/jstarke/Library/Logs/DiagnosticReports/***_2013-03-28-135722_macmini1.crash

Update #2 I found the crash reports mentioned above. Here is the latest crash report information, including the crashed thread

Process:         *** [29880]
Path:            /Users/*/Library/Application Support/iPhone Simulator/*/***.app/***
Identifier:      ***
Version:         ??? (???)
Code Type:       X86 (Native)
Parent Process:  launchd [409]

Date/Time:       2013-03-29 11:44:48.882 -0700
OS Version:      Mac OS X Server 10.7.5 (11G63)
Report Version:  9

Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_PROTECTION_FAILURE at 0x00000000bf7fff7c

VM Regions Near 0xbf7fff7c:
    Stack                  00000000b050b000-00000000b052c000 [  132K] rw-/rwx SM=COW  
--> Stack                  00000000bc000000-00000000bf800000 [ 56.0M] ---/rwx SM=NUL  
    Stack                  00000000bf800000-00000000c0000000 [ 8192K] rw-/rwx SM=COW  

Application Specific Information:
iPhone Simulator 358.4, iPhone OS 6.0 (iPhone/10A403)


Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0   libsystem_c.dylib             
0x954d458c szone_malloc_should_clear + 12
1   libsystem_c.dylib             
0x954d566b szone_malloc + 24
2   libsystem_c.dylib             
0x9550b962 malloc_zone_malloc + 77
3   libsystem_c.dylib             
0x9550c882 malloc + 50
4   libobjc.A.dylib               
0x041985c9 class_copyProtocolList + 157
5   CoreFoundation                
0x03f72962 __methodDescriptionForSelector + 178
6   CoreFoundation                
0x03fe65a3 -[NSObject(NSObject) methodSignatureForSelector:] + 51
7   ***                  
0x00254352 monotouch_trampoline + 82
8   ???                           
0x16c4ab0b 0 + 381987595
9   ???                           
0x16c7428c 0 + 382157452
10  ???                           
0x16c743dc 0 + 382157788
11  ***                  
0x0004cf22 mono_jit_runtime_invoke + 722
12  ***                  
0x001b03fe mono_runtime_invoke + 126
13  ***                  
0x00255166 monotouch_trampoline + 3686

Lines 8 - 13 repeat a large number of times (no additional information)

506 ???                           
0x16c4ab0b 0 + 381987595
507 ???                           
0x16c7428c 0 + 382157452
508 ???                           
0x16c743dc 0 + 382157788
509 ***
0x0004cf22 mono_jit_runtime_invoke + 722
510 ***                  
0x001b03fe mono_runtime_invoke + 126
511 ***                  
0x00255166 monotouch_trampoline + 3686

Update #3 In an effort to get some more information, I decided to override all of the methods in the CDVViewController within my local WebViewController, and then return the value from the base equivalent of each method, and set a breakpoint on the method, and put a Console.WriteLine saying that we entered and exited each method.

To my surprise, the reason for the many many duplications in Update #2 has to do with the fact that when WebViewController.ShouldAutoRotateToInterfaceOrientation is called, we call the base class CDVViewController.ShouldAutoRotateToInterfaceOrientation, which apparently in turn calls WebViewController.ShouldAutoRotateToInterfaceOrientation, and so on.

Looking at the source code for the version of Cordova I'm using (here), shouldAutorotateToInterfaceOrientation: would call supportsOrientation:, which would return from an NSArray.

I can't see any reason why CDVViewController.ShouldAutoRotateToInterfaceOrientation should ever call WebViewController.ShouldAutoRotateToInterfaceOrientation. Does anyone in the Xamarin or Cordova community have any idea?


回答1:


If anyone else is experiencing a similar issue relating to Bindings, I managed to get this working thanks to the advice of Rolf Bjarne Kvinge (Binding issues: extending a class leads method calling itself?)

It turns out that a flag that I was using (without really understanding what it did) was to blame for this. When generating the DLL using btouch the -e flag Generates smaller classes that can not be subclassed.

Removing this will likely solve your problem, like it did for me.



来源:https://stackoverflow.com/questions/15693762/issues-with-bindings-calling-base-method-on-binding-class-calls-override-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!