从我的问题:
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");
- }