简体   繁体   中英

Workaround to avoid JIT compile limit on Xamarin iOS

i have a class that binds a obj-c object

public unsafe partial class CUSTOMER_INFO : NSObject {

        [Export ("signature", ArgumentSemantic.Retain)]
        get {
            NSData ret;
            if (IsDirectBinding) {
                ret =  Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("signature")));
            } else {
                ret =  Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("signature")));
            }
            if (!IsNewRefcountEnabled ())
                __mt_Signature_var = ret;
            return ret;
        }

        [Export ("setSignature:", ArgumentSemantic.Retain)]
        set {
            if (value == null)
                throw new ArgumentNullException ("value");
            if (IsDirectBinding) {
                global::ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setSignature:"), value.Handle);
            } else {
                global::ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setSignature:"), value.Handle);
            }
            if (!IsNewRefcountEnabled ())
                __mt_Signature_var = value;
        }
}

but when i declare it and i pass it to a method (inside a ios binding library), i get the known exception

System.ExecutionEngineException: Attempting to JIT compile method 'CUSTOMER_INFO:set_Signature (Foundation.NSData)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.

UPDATE after suggestion by user @SushiHangover In my iOS binding library project in generated code I tried this workaround:

[Register("CUSTOMER_INFO", true)]
//public unsafe partial class CUSTOMER_INFO : NSObject {
public unsafe partial class CUSTOMER_INFO_GENERIC<T> : NSObject where T : NSObject
{
    [CompilerGenerated]
    static readonly IntPtr class_ptr = Class.GetHandle ("CUSTOMER_INFO");

    public override IntPtr ClassHandle { get { return class_ptr; } }

    [CompilerGenerated]
    [EditorBrowsable (EditorBrowsableState.Advanced)]
    [Export ("init")]
    public CUSTOMER_INFO_GENERIC () : base (NSObjectFlag.Empty)
    {
        IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
        if (IsDirectBinding) {
            InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
        } else {
            InitializeHandle (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, global::ObjCRuntime.Selector.GetHandle ("init")), "init");
        }
    }

    [CompilerGenerated]
    [EditorBrowsable (EditorBrowsableState.Advanced)]
    protected CUSTOMER_INFO_GENERIC(NSObjectFlag t) : base (t)
    {
        IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
    }

    [CompilerGenerated]
    [EditorBrowsable (EditorBrowsableState.Advanced)]
    protected internal CUSTOMER_INFO_GENERIC(IntPtr handle) : base (handle)
    {
        IsDirectBinding = GetType ().Assembly == global::ApiDefinition.Messaging.this_assembly;
    }

    // other methods....
    // .................

    [CompilerGenerated]
    object __mt_Signature_var;
    [CompilerGenerated]
    public virtual NSData SignatureNoJit {
        [Export ("signature", ArgumentSemantic.Retain)]
        get {
            NSData ret;
            if (IsDirectBinding) {
                ret =  Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSend (this.Handle, Selector.GetHandle ("signature")));
            } else {
                ret =  Runtime.GetNSObject<NSData> (global::ApiDefinition.Messaging.IntPtr_objc_msgSendSuper (this.SuperHandle, Selector.GetHandle ("signature")));
            }
            if (!IsNewRefcountEnabled ())
                __mt_Signature_var = ret;
            return ret;
        }

        [Export ("setSignature:", ArgumentSemantic.Retain)]
        set {
            if (value == null)
                throw new ArgumentNullException ("value");
            if (IsDirectBinding) {
                global::ApiDefinition.Messaging.void_objc_msgSend_IntPtr (this.Handle, Selector.GetHandle ("setSignature:"), value.Handle);
            } else {
                global::ApiDefinition.Messaging.void_objc_msgSendSuper_IntPtr (this.SuperHandle, Selector.GetHandle ("setSignature:"), value.Handle);
            }
            if (!IsNewRefcountEnabled ())
                __mt_Signature_var = value;
        }
    }

    [CompilerGenerated]
    protected override void Dispose (bool disposing)
    {
        base.Dispose (disposing);
        if (Handle == IntPtr.Zero) {
            __mt_Signature_var = null;
        }
    }
}

public class CUSTOMER_INFO_NOJIT : CUSTOMER_INFO_GENERIC<NSData>
{
    // A specialized subclass and this is passed to your ObjC-based method
}

But when i call

NSData tmp = NSData.FromArray(new byte[] { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF });
CUSTOMER_INFO_NOJIT CustomerInfo = new CUSTOMER_INFO_NOJIT();
CustomerInfo.CardHolderEmail = CardHolderEMail;
CustomerInfo.CardHolderMobile = CardHolderMobilePhone;
CustomerInfo.SignatureNoJit = tmp;

I get this exception again:

System.ExecutionEngineException: Attempting to JIT compile method 'CUSTOMER_INFO_GENERIC`1:set_SignatureNoJit (Foundation.NSData)' while running with --aot-only. See http://docs.xamarin.com/ios/about/limitations for more information.

Anybody can suggest me a workaround/pattern to avoid this exception? Thank you!

Lewix

(I might need more coffee...so take this with grain of salt... :-)

This:

public unsafe partial class CUSTOMER_INFO : NSObject {
   ~~~~
}

Becomes:

public unsafe partial class CUSTOMER_INFO_GENERIC<T> : NSObject where T : NSObject {
  ~~~~
}

class CUSTOMER_INFO : CUSTOMER_INFO_GENERIC<NSData>
{
  // A specialized subclass and this is passed to your ObjC-based method
}

And thus this in your set and the get return can be resolved as NSData vs. NSObject and no jitting is required and the compiler created/resolved the classes...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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