2013-04-01 38 views
1

我還有一個與綁定有關的問題(Issues with Bindings: Calling base method on binding class calls override method. Leads to infinite recursion),它已經變得很笨重了,所以我想我會從一個新的問題開始,這個問題包含了我現在所知道的最好的信息。綁定問題:擴展一個類自動調用的方法?

我想在我正在MonoTouch中使用的項目中使用Cordova。我一直在爲科爾多瓦工作。

這裏是我的科爾多瓦2.4.0類(點擊此處下載https://github.com/apache/cordova-ios/tree/2.4.0/CordovaLib/Classes)結合:(注意這不是一個完整的約束力,只是個我需要到目前爲止

interface CDVScreenOrientationDelegate { 
    [Export ("supportedInterfaceOrientations")] 
    uint SupportedInterfaceOrientations(); 

    [Export ("shouldAutorotateToInterfaceOrientation:")] 
    bool ShouldAutoRotateToInterfaceOrientation (UIInterfaceOrientation interfaceOrientation); 

    [Export ("shouldAutorotate")] 
    bool ShouldAutoRotate(); 
} 

[BaseType (typeof (UIViewController))] 
interface CDVViewController : CDVScreenOrientationDelegate { 
    [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 orientation); 

    [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); 
} 

[BaseType (typeof(NSObject))] 
interface CDVWhitelist { 
    [Export ("whitelist")] 
    NSArray Whitelist { get; } 

    [Export ("expandedWhitelist")] 
    NSArray ExpandedWhitelist { get; } 

    [Export ("allowAll")] 
    bool AllowAll { get; } 

    [Export ("initWithArray:")] 
    IntPtr Constructor (NSArray array); 

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

    [Export ("schemeIsAllowed:")] 
    bool SchemeIsAllowed (string scheme); 

    [Export ("errorStringForURL:")] 
    string ErrorStringForUrl (NSUrl url); 
} 

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

    [Export ("viewController")] 
    UIViewController ViewController { get; set; } 

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

    [Export ("hasPendingOperation")] 
    bool HasPendingOperation { get; } 

    [Export ("initWithWebView:")] 
    CDVPlugin InitWithWebView (UIWebView theWebView); 

    [Export ("handleOpenURL:")] 
    void HandleOpenUrl (NSNotification notification); 

    [Export ("onAppTerminate")] 
    void OnAppTerminate(); 

    [Export ("onMemoryWarning")] 
    void OnMemoryWarning(); 

    [Export ("onReset")] 
    void OnReset(); 

    [Export ("appDelegate")] 
    NSObject AppDelegate(); 
} 

這是使用miguel.de.icaza的協議從Monotouch Binding Syntax For Protocols。這並不一定是也被CDVViewController

@interface CDVViewController : UIViewController <UIWebViewDelegate, CDVScreenOrientationDelegate>{ 
    @protected 
    CDVCommandDelegateImpl* _commandDelegate; 
    @protected 
    CDVCommandQueue* _commandQueue; 
    NSString* _userAgent; 
} 

或者採用UIWebViewDelegate,我發現羅爾夫Bjarne的Kvinge建議採用語法在http://monotouch.2284126.n4.nabble.com/Objective-C-protocol-binding-method-not-invoked-td4105828.html。不幸的是,我無法得到這個工作,因爲當我試圖建立我的綁定,它會抱怨不能符合System.TypeString。但這是一個不同的問題。

當我嘗試子類CDVViewController,我遇到了其他問題。具體viewDidLoad中被調用後,系統會調用我的子類ShouldAutoRotateToInterfaceOrientation

爲了證實這一點,我做了以下內容:

public class WebViewController : CDVViewController 
{ 
    public override bool ShouldAutoRotateToInterfaceOrientation (MonoTouch.UIKit.UIInterfaceOrientation interfaceOrientation) 
    { 
     Console.WriteLine ("Enter ShouldAutoRotateToInterfaceOrientation"); 
     var output = base.ShouldAutoRotateToInterfaceOrientation; 
     Console.WriteLine ("Leave ShouldAutoRotateToInterfaceOrientation"); 
     return output; 
    } 
} 

我把一個斷點ShouldAutoRotateToInterfaceOrientation裏面,當我沿着方法步驟,當我到達base.ShouldAutoRotateToInterfaceOrientation,它只是跳回到這個方法的開始,我的調用堆棧現在增加了Cordova.CDVViewController.ShouldAutoRotateToInterfaceOrientation,但是看着這個方法的源代碼(可用here),它從來沒有試圖調用自己或者一個子類實現。相反,它會在內部調用supportsOrientation:,這會檢查數組以確定是否支持此方向。

因爲知道supportsOrientation:最後被調用,所以我試着從ShouldAutoRotateToInterfaceOrientation中調用它,但是我只是在該方法中調用自己的行爲。

如果我直接實例化CDVViewController,那麼一切似乎按預期工作,但我需要重寫我的項目的一些方法。當我擴展CDVViewController, 時,這種行爲開始發生。

我很困惑這一點,我不知道我在做什麼錯,所以任何幫助將不勝感激。

更新#1根據Rolf的請求,這裏是生成的類。我希望這是你正在尋找的。出於篇幅的原因,我將它作爲Gist添加到這裏https://gist.github.com/innopal/5288047

+0

你可以找到爲綁定生成的代碼,看看/發佈它看起來像什麼?如果右鍵單擊解決方案並選擇查看所有文件,則生成的文件位於某個子目錄中(不能完全記住名稱,但不應該花很長時間才能找到它)。 –

+0

感謝您的回覆Rolf。我在我生成的DLL中找到這些。我希望這有助於https://gist.github.com/innopal/5288047 –

+0

您是使用綁定項目還是手動使用btouch? –

回答

0

正如Rolf指出的那樣,解決這個問題的方法是在我的參數中包含-e標誌。

如幫助btouch指出,

-e Generates smaller classes that cannot be subclassed (previously called 'external mode'). 

所以這裏的問題是,我在不知不覺中使用一個標誌,特別是使類unsubclassable,然後試圖繼承他們。