本文介绍了如何移植“method_getImplementation"和“method_setImplementation"到 MonoTouch?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
从我这里的问题:没有子类化 UIView 或 UIViewController:是否可以捕获是否添加了子视图?
我想知道如何将代码从答案移植到 MonoTouch.它基本上用一个新方法替换一个方法,然后调用旧方法而不进行子类化.是否有可能让这个指针在 MonoTouch 中工作?
I'm wondering how to port the code from the answer to MonoTouch. It basically replaces a method with a new one and then calls the old one without subclassing. Is it possible at all to get this pointer juggling it to work in 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# 代码实现:
This looks like a good candidate for us to provide a general purpose mechanism to hijack methods. Here is an implementation in pure C# code that you can use in the meantime:
[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");
}
这篇关于如何移植“method_getImplementation"和“method_setImplementation"到 MonoTouch?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!