【问题标题】:Workaround to avoid JIT compile limit on Xamarin iOS避免 Xamarin iOS 上的 JIT 编译限制的解决方法
【发布时间】:2023-11-01 14:59:01
【问题描述】:

我有一个绑定 obj-c 对象的类

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

但是当我声明它并将它传递给一个方法(在 ios 绑定库中)时,我得到了已知的异常

System.ExecutionEngineException:尝试 JIT 编译方法 'CUSTOMER_INFO:set_Signature (Foundation.NSData)' 同时运行 --aot-only。请参阅http://docs.xamarin.com/ios/about/limitations 了解更多信息。

更新在用户@SushiHangover 的建议下 在生成代码的 iOS 绑定库项目中,我尝试了这种解决方法:

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

但是当我打电话时

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;

我又遇到了这个异常:

System.ExecutionEngineException:尝试 JIT 编译方法 'CUSTOMER_INFO_GENERIC`1:set_SignatureNoJit (Foundation.NSData)' 使用 --aot-only 运行时。看 http://docs.xamarin.com/ios/about/limitations 了解更多信息。

任何人都可以建议我一个解决方法/模式来避免这个异常? 谢谢!

刘易斯

【问题讨论】:

    标签: ios xamarin jit


    【解决方案1】:

    (我可能需要更多的咖啡......所以把这个和一粒盐一起吃吧......:-)

    这个:

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

    变成:

    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
    }
    

    因此,this 在您的 setget 返回可以解析为 NSDataNSObject 并且不需要 jitting 并且编译器创建/解析类...

    【讨论】:

    • 嗨@SushiHangover,你能检查我更新的帖子(谢谢你的建议)和(我希望!)你能帮我吗?如果你住在意大利附近,我会提供啤酒:)
    • 我也尝试在ios项目中启用“启用通用值类型共享”
    • 在 OSX 平台上测试后,没有出现 JIT 异常,谁能解释一下为什么?
    • 有关于我的问题的消息吗?
    • @LuiginoDeTogni 没有看到您较新的 cmets 和更新...我稍后再看...仅供参考:OS-X 允许动态代码生成/抖动,因此您只会看到这种类型的iOS 上的问题...
    最近更新 更多