ios – 如何将“method_getImplementation”和“method_setImplementation”移植到MonoTouch?

从我的问题: Without subclassing a UIView or UIViewController: possible to catch if a subview was added?

我想知道如何从MonoTouch的答案中移植代码.它基本上用一个新方法替换一个方法,然后在没有子类化的情况下调用旧方法.是否有可能让这个指针在MonoTouch中工作?

//Makes views announce their change of superviews
Method method = class_getInstanceMethod([UIView class],@selector(willMoveToSuperview:));
IMP originalImp = method_getImplementation(method);

void (^block)(id,UIView*) = ^(id _self,UIView* superview) {
    [_self willChangeValueForKey:@"superview"];
    originalImp(_self,@selector(willMoveToSuperview:),superview);
    [_self didChangeValueForKey:@"superview"];
};

IMP newImp = imp_implementationWithBlock((__bridge void*)block);
method_setImplementation(method,newImp);

解决方法

这似乎是我们提供劫持方法的通用机制的一个很好的候选者.以下是纯C#代码的实现,您可以在此期间使用它:
[DllImport ("/usr/lib/libobjc.dylib")]
    extern static IntPtr class_getInstanceMethod (IntPtr classHandle,IntPtr Selector);
    [DllImport ("/usr/lib/libobjc.dylib")]
    extern static Func<IntPtr,IntPtr,IntPtr> method_getImplementation (IntPtr method);
    [DllImport ("/usr/lib/libobjc.dylib")]
    extern static IntPtr imp_implementationWithBlock (ref BlockLiteral block);
    [DllImport ("/usr/lib/libobjc.dylib")]
    extern static void method_setImplementation (IntPtr method,IntPtr imp);

    static Func<IntPtr,IntPtr> original_impl;

    void HijackWillMoveToSuperView ()
    {
        var method = class_getInstanceMethod (new UIView ().ClassHandle,new Selector ("willMoveToSuperview:").Handle);
        original_impl = method_getImplementation (method);
        var block_value = new BlockLiteral ();
        CaptureDelegate d = MyCapture;
        block_value.SetupBlock (d,null);
        var imp = imp_implementationWithBlock (ref block_value);
        method_setImplementation (method,imp);
    }

    delegate void CaptureDelegate (IntPtr block,IntPtr self,IntPtr uiView);

    [MonoPInvokeCallback (typeof (CaptureDelegate))]
    static void MyCapture (IntPtr block,IntPtr uiView)
    {
        Console.WriteLine ("Moving to: {0}",Runtime.GetNSObject (uiView));
        original_impl (self,uiView);
        Console.WriteLine ("Added");
    }

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...