ios - 如何将 "method_getImplementation"和 "method_setImplementation"移植到 MonoTouch?

标签 ios xamarin.ios

从我这里的问题: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,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 self, IntPtr uiView)
    {
        Console.WriteLine ("Moving to: {0}", Runtime.GetNSObject (uiView));
        original_impl (self, uiView);
        Console.WriteLine ("Added");
    }

关于ios - 如何将 "method_getImplementation"和 "method_setImplementation"移植到 MonoTouch?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14127453/

相关文章:

ios - 为什么UITabbarController会触底

IOS:通过一对多关系获取核心数据

ios - NSCoding:自定义类未归档,但类成员为空/无

c# - 将 MasterDetailPage 中的导航与 Autofac 和 Xamarin.Forms 一起使用

xamarin - 如何更改 Xamarin.iOS 项目的 IPA 输出位置?

ios - 如何设置imageView的圆角半径?

iphone - 如何使用 CALayer 或 CoreGraphics 函数绘制角度渐变?

ios - 静音本地通知 IOS

objective-c - 如何在monotouch中改变UIbutton的文字大小?

c# - 尝试运行Monotouch-bindings示例Facebook时出错