1

Xamarin を使用して一部の外部コードのバインディング ライブラリを作成すると、(私が知る限り) プロトコルにすべてのセレクターを実装しているにもかかわらず、Obj-C コードでデリゲートがconformsToProtocolチェックに合格しないという問題が発生しました。その結果、コードは機能しません。

Objective-C ヘッダー ファイルは次のようになります ( https://github.com/janrain/jump.ios/blob/master/Janrain/JRCapture/Classes/JRCapture.h )。

@protocol JRCaptureDelegate <NSObject>
@optional
- (void)engageAuthenticationDialogDidFailToShowWithError:(NSError *)error;

- (void)engageAuthenticationDidCancel;

- (void)engageAuthenticationDidSucceedForUser:(NSDictionary *)engageAuthInfo forProvider:(NSString *)provider;

 - (void)engageAuthenticationDidFailWithError:(NSError *)error forProvider:(NSString *)provider;

- (void)captureSignInDidSucceedForUser:(JRCaptureUser *)captureUser
                            status:(JRCaptureRecordStatus)captureRecordStatus;

- (void)captureSignInDidFailWithError:(NSError *)error;

- (void)registerUserDidSucceed:(JRCaptureUser *)registeredUser;

- (void)registerUserDidFailWithError:(NSError *)error;

- (void)refreshAccessTokenDidSucceedWithContext:(id <NSObject>)context;

- (void)refreshAccessTokenDidFailWithError:(NSError *)error context:(id <NSObject>)context;
@end

そして、ApiDefinition.csこれに対応する の部分は次のとおりです。

[Model, BaseType (typeof (NSObject))]
public partial interface JRCaptureDelegate {

    [Export ("engageAuthenticationDidCancel")]
    void EngageAuthenticationCancelled ();

    [Export ("engageAuthenticationDidSucceedForUser:forProvider:")]
    void AuthenticationSucceededForProvider (NSDictionary engageAuthInfo, string provider);

    [Export ("captureSignInDidSucceedForUser:status:")]
    void SignInSucceeded (JRCaptureUser captureUser, JRCaptureRecordStatus captureRecordStatus);

    [Export ("registerUserDidSucceed:")]
    void  RegisterUserSucceeded(JRCaptureUser registeredUser);

    [Export ("refreshAccessTokenDidSucceedWithContext:")]
    void  RefreshAccessTokenSucceeded(NSObject context);

    //- (void)engageAuthenticationDialogDidFailToShowWithError:(NSError *)error
    [Export ("engageAuthenticationDialogDidFailToShowWithError:")]
    void DialogFailedToShow (NSError error);

    //- (void)engageAuthenticationDidFailWithError:(NSError *)error forProvider:(NSString *)provider;
    [Export("engageAuthenticationDidFailWithError:forProvider:")]
    void AuthenticationFailedForProvider (NSError error, NSString provider);

    //- (void)captureSignInDidFailWithError:(NSError *)error;
    [Export("captureSignInDidFailWithError:")]
    void SignInFailed (NSError error);

    //- (void)registerUserDidFailWithError:(NSError *)error;
    [Export("registerUserDidFailWithError:")]
    void RegisterUserFailed (NSError error);

    //- (void)refreshAccessTokenDidFailWithError:(NSError *)error context:(id <NSObject>)context;
    [Export("refreshAccessTokenDidFailWithError:context:")]
    void RefreshAccessTokenFailed (NSError error, NSObject context);
}

これはコンパイルされ、デリゲート クラスのメソッドを呼び出したくない特定のメソッドに問題があったことを除けば、問題なく動作しているように見えます。たくさん掘り下げた(そして、Objective-C を難しい方法で学習した)後、私は問題を切り分けたと信じています。私がバインドしているライブラリには、これがあります:

    if ([delegate conformsToProtocol:@protocol(JRCaptureDelegate)] &&
        [delegate respondsToSelector:@selector(captureSignInDidSucceedForUser:status:)])

少しDLog調べてみると、デリゲートがチェックに失敗していることがわかりましたconformsToProtocol(ただし、チェックには合格していrespondsToSelectorます)。

conformsToProtocolでは、プロトコルにすべてのメソッドを実装しているのに、なぜクラスが失敗するのでしょうか。ここで何が欠けていますか?

取るさまざまなメソッドに渡されるデリゲートを実装する私のクラスは、JRCaptureDelegate次のようになります。

public class SignIn : JRCaptureDelegate
{
     // overrides for each method
}
4

1 に答える 1

2

わかりました、私はそれをクラックしたかもしれないと思います。クラスに属性を追加しましたAdopts(Xamarin ドキュメントのさまざまな場所で漠然と言及されていますが、バインディング ライブラリを作成するときに行うべきこととして実際には提案されていません)。だから今私はこれを持っています:

[Adopts("JRCaptureDelegate")] 
public class SignIn : JRCaptureDelegate
{
     // overrides for each method
}

そして今、それはconformsToProtocolチェックを通過します。JRCaptureDelegate インターフェイス/プロトコルを実装しているため、これが自動化されない理由がわかりません。

于 2013-08-14T14:06:49.300 に答える