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