Xamarin仅在设备上丢失了自定义objc类别(无法识别的选择器发送到实例)

情况:

  • 我有一个在我的objc静态库中定义的自定义类别:

    @implementation UIViewController (Colorful) -(void)changeColor:(UIColor *)color { self.view.backgroundColor = color; } @end 
  • 它绑定到Xamarin项目:

     [Category, BaseType(typeof(UIViewController))] interface UIViewController_Colorful { [Export ("changeColor:")] void ChangeColor(UIColor color); } 
  • 此类别用于以下代码:

     public override bool FinishedLaunching (UIApplication app, NSDictionary options) { window = new UIWindow (UIScreen.MainScreen.Bounds); UIViewController vc = new UIViewController (); vc.ChangeColor (UIColor.Red); window.RootViewController = vc; window.MakeKeyAndVisible (); return true; } 

它在模拟器上工作正常,但在设备上我得到以下exception。 即使在库本身内调用类别,也会出现相同的情况。

我的设置是OS X 10.10,Xcode 6.3,Xamarin studio 5.9.3,Xamarin.iOS 8.10.1.64,Mono 4.0.1

谢谢。

 $exception {Foundation.MonoTouchException: Objective-C exception thrown. Name: NSInvalidArgumentException Reason: -[UIViewController changeColor:]: unrecognized selector sent to instance 0x1759cd70 at ObjCRuntime.Runtime.ThrowNSException (IntPtr ns_exception) [0x00000] in /Users/builder/data/lanes/1503/e6ebd18b/source/maccore/src/ObjCRuntime/Runtime.cs:167 at ObjCRuntime.Runtime.throw_ns_exception (IntPtr exc) [0x00000] in :0 at (wrapper native-to-managed) ObjCRuntime.Runtime:throw_ns_exception (intptr) at (wrapper managed-to-native) UIKit.UIApplication:UIApplicationMain (int,string[],intptr,intptr) at UIKit.UIApplication.Main (System.String[] args, IntPtr principal, IntPtr delegate) [0x00005] in /Users/builder/data/lanes/1503/e6ebd18b/source/maccore/src/UIKit/UIApplication.cs:63 at UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0001c] in /Users/builder/data/lanes/1503/e6ebd18b/source/maccore/src/UIKit/UIApplication.cs:46 at XTestApp.Application.Main (System.String[] args) [0x00008] in /Volumes/MacWork/xamarin/BindingTest/xamarin/XTest/XTestApp/Main.cs:17 NSInvalidArgumentException: -[UIViewController changeColor:]: unrecognized selector sent to instance 0x1759cd70 0 CoreFoundation 0x264de007  + 150 1 libobjc.A.dylib 0x3478dc8b objc_exception_throw + 38 2 CoreFoundation 0x264e3409  + 0 3 CoreFoundation 0x264e1327  + 714 4 CoreFoundation 0x26410e78 _CF_forwarding_prep_0 + 24 5 XTestApp 0x0026e21c wrapper_managed_to_native_ApiDefinition_Messaging_void_objc_msgSend_IntPtr_intptr_intptr_intptr + 228 6 XTestApp 0x0026d4c0 Binding_UIViewController_Colorful_ChangeColor_UIKit_UIViewController_UIKit_UIColor + 432 7 XTestApp 0x000c8424 XTestApp_AppDelegate_FinishedLaunching_UIKit_UIApplication_Foundation_NSDictionary + 592 8 XTestApp 0x0022c4d8 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 224 9 XTestApp 0x0029d933 mono_jit_runtime_invoke + 1190 10 XTestApp 0x002da025 mono_runtime_invoke + 88 11 XTestApp 0x0026e605 native_to_managed_trampoline_1 + 420 12 XTestApp 0x0026ea31 -[AppDelegate application:didFinishLaunchingWithOptions:] + 100 13 UIKit 0x29b9e293  + 374 14 UIKit 0x29d94b29  + 2444 15 UIKit 0x29d971e9  + 1412 16 UIKit 0x29da1e69  + 36 17 UIKit 0x29d9598b  + 130 18 FrontBoardServices 0x2cf95ec9  + 16 19 CoreFoundation 0x264a3fd5  + 12 20 CoreFoundation 0x264a3299  + 216 21 CoreFoundation 0x264a1dd3  + 1714 22 CoreFoundation 0x263ee201 CFRunLoopRunSpecific + 476 23 CoreFoundation 0x263ee013 CFRunLoopRunInMode + 106 24 UIKit 0x29b97e67  + 558 25 UIKit 0x29b92a59 UIApplicationMain + 1440 26 XTestApp 0x0010710c wrapper_managed_to_native_UIKit_UIApplication_UIApplicationMain_int_string___intptr_intptr + 272 27 XTestApp 0x000e56dc UIKit_UIApplication_Main_string___intptr_intptr + 52 28 XTestApp 0x000e569c UIKit_UIApplication_Main_string___string_string + 204 29 XTestApp 0x000c8130 XTestApp_Application_Main_string__ + 172 30 XTestApp 0x0022c4d8 wrapper_runtime_invoke_object_runtime_invoke_dynamic_intptr_intptr_intptr_intptr + 224 31 XTestApp 0x0029d933 mono_jit_runtime_invoke + 1190 32 XTestApp 0x002da025 mono_runtime_invoke + 88 33 XTestApp 0x002dd4c7 mono_runtime_exec_main + 282 34 XTestApp 0x002dd309 mono_runtime_run_main + 476 35 XTestApp 0x0028c5d9 mono_jit_exec + 48 36 XTestApp 0x0032d3ec xamarin_main + 2184 37 XTestApp 0x0026f4dd main + 112 38 libdyld.dylib 0x34d19aaf  + 2 } Foundation.MonoTouchException 

所有包含Objective-C类别的静态库都必须将-ObjC传递给本机链接器,否则可能会删除类别( 如Apple所述 )。

这可以通过两种方式实现:

  1. -gcc_flags -ObjC到项目的iOS Build选项中的其他mtouch参数中,用于每个(设备)项目配置。
  2. 如果使用绑定项目,则可以修改LinkWith属性以包含此链接器标志:

     [assembly: LinkWith ("...", LinkerFlags = "-ObjC")]