xcode 调用 iPhone 静态库中包含的类别的方法会导致 NSInvalidArgumentException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/932856/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Calling method on category included from iPhone static library causes NSInvalidArgumentException
提问by Corey Floyd
I have created a static library to house some of my code like categories.
我创建了一个静态库来容纳我的一些代码,如类别。
I have a category for UIViews in "UIView-Extensions.h" named Extensions.
我在名为 Extensions 的“UIView-Extensions.h”中有一个 UIViews 类别。
In this category I have a method called:
在这个类别中,我有一个方法叫做:
- (void)fadeOutWithDelay:(CGFloat)delay duration:(CGFloat)duration;
Calling this method works fine on the simulator on Debug configuration.
在调试配置的模拟器上调用此方法工作正常。
However, if try to run the app on the device I get a NSInvalidArgumentException:
但是,如果尝试在设备上运行该应用程序,我会收到 NSInvalidArgumentException:
[UIView fadeOutWithDelay:duration:]: unrecognized selector sent to instance 0x1912b0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIView fadeOutWithDelay:duration:]: unrecognized selector sent to instance 0x1912b0
It seems for some reason UIView-Extensions.h is not being included in the device builds.
似乎由于某种原因 UIView-Extensions.h 没有包含在设备版本中。
What I have checked/tried
我检查过/尝试过的
I did try to include another category for NSString, and had the same issue.
我确实尝试为 NSString 包含另一个类别,但遇到了同样的问题。
Other files, like whole classes and functions work fine. It is an issue that onlyhappens with categories.
其他文件,如整个类和函数工作正常。这是一个只发生在类别上的问题。
I did a clean all targets, which did not fix the problem.
我清理了所有目标,但没有解决问题。
I checked the static library project, the categories are included in the target's "copy headers" and "compile sources" groups.
我检查了静态库项目,类别包含在目标的“复制标题”和“编译源”组中。
The static library is included in the main projects "link binary with library" group.
静态库包含在主要项目“用库链接二进制文件”组中。
Another project I have added the static library to works just fine.
我添加了静态库的另一个项目可以正常工作。
I deleted and re-added the static library with no luck
我删除并重新添加了静态库,但没有运气
-ObjC linker flag is set
-ObjC 链接器标志已设置
Any ideas?
有任何想法吗?
nm output
纳米输出
libFJSCodeDebug.a(UIView-Extensions.o):
000004d4 t -[UIView(Extensions) changeColor:withDelay:duration:]
00000000 t -[UIView(Extensions) fadeInWithDelay:duration:]
000000dc t -[UIView(Extensions) fadeOutWithDelay:duration:]
00000abc t -[UIView(Extensions) firstResponder]
000006b0 t -[UIView(Extensions) hasSubviewOfClass:]
00000870 t -[UIView(Extensions) hasSubviewOfClass:thatContainsPoint:]
000005cc t -[UIView(Extensions) rotate:]
000002d8 t -[UIView(Extensions) shrinkToSize:withDelay:duration:]
000001b8 t -[UIView(Extensions) translateToFrame:delay:duration:]
U _CGAffineTransformRotate
000004a8 t _CGPointMake
U _CGRectContainsPoint
U _NSLog
U _OBJC_CLASS_$_UIColor
U _OBJC_CLASS_$_UIView
U ___CFConstantStringClassReference
U ___addsf3vfp
U ___divdf3vfp
U ___divsf3vfp
U ___extendsfdf2vfp
U ___muldf3vfp
U ___truncdfsf2vfp
U _objc_enumerationMutation
U _objc_msgSend
U _objc_msgSend_stret
U dyld_stub_binding_helper
采纳答案by Corey Floyd
The only solution that worked was to include:
唯一有效的解决方案是包括:
"-all_load"
“-all_load”
in other linker flags.
在其他链接器标志中。
EDIT:Be sure to add this flag to the project including the static library, not to the static library itself.
编辑:确保将此标志添加到包含静态库的项目中,而不是静态库本身。
I know this isn't the correct method, but it is working for now.
我知道这不是正确的方法,但它现在有效。
It maybe a OS 3.0 issue since this was the work around for Three20 as well.
这可能是 OS 3.0 问题,因为这也是 Three20 的工作。
回答by Jason Coco
Unfortunately, due to the what categories work and the dynamic nature of the Objective-C runtime, not everything works well with static libraries. The reason you get this error is that the category implementation in the static library is never actually linked into the executable image because the compiler has no way of knowing that the implementation code will be needed at run-time.
不幸的是,由于什么类别起作用以及 Objective-C 运行时的动态特性,并不是所有的东西都适用于静态库。出现此错误的原因是静态库中的类别实现实际上从未链接到可执行映像中,因为编译器无法知道在运行时需要实现代码。
In order to cure this, you can force the linker to copy object files from a static archive for any and all Objective-C Class and Category images. The downside is that your executable will include image code for classes that you may not be using at all. To get the linker to include the category code, add -ObjC
to the OTHER_LD_FLAGS
build setting in Xcode. Your category implementation will now be copied from the static archive to your executable and you won't get the runtime exception.
为了解决这个问题,您可以强制链接器从静态存档中为任何和所有 Objective-C 类和类别图像复制目标文件。缺点是您的可执行文件将包含您可能根本不使用的类的图像代码。要让链接器包含类别代码,请添加-ObjC
到OTHER_LD_FLAGS
Xcode 中的构建设置。您的类别实现现在将从静态存档复制到您的可执行文件,您将不会收到运行时异常。
回答by ev0
I just spoke to an Apple engineer about this, and this has been addressed in ld with versions >100. This is included in XCode4. He walked me through this and I tried it myself and indeed the category problem is fixed.
我刚刚和一位 Apple 工程师谈过这个问题,这个问题已经在 ld 版本>100 中得到解决。这包含在 XCode4 中。他带我完成了这个,我自己尝试了,确实类别问题已解决。
Take out "-all_load" and go back to "-ObjC" in your Build Settings with the new linker.
取出“-all_load”并使用新链接器返回“构建设置”中的“-ObjC”。
回答by Erik Doernenburg
If you are on Xcode 3.2 you can avoid using -all_load and instead use -force_load for just the library in question, which should be slightly more efficient.
如果您使用的是 Xcode 3.2,则可以避免使用 -all_load,而是将 -force_load 仅用于相关库,这样效率会更高一些。
This is described in a recently updated Apple Technical QA: http://developer.apple.com/mac/library/qa/qa2006/qa1490.html
这在最近更新的 Apple 技术 QA 中有描述:http: //developer.apple.com/mac/library/qa/qa2006/qa1490.html
回答by tonklon
The issue that -all_load
or -force_load
linker flags were needed to link categories has been fixed in LLVM. The fix ships as part of LLVM 2.9 The first Xcode version to contain the fix is Xcode 4.2 shipping with LLVM 3.0. The mentioned fixes are no longer needed when working with Xcode 4.2. The -ObjC
flag is still needed when linking ObjC binaries
这个问题-all_load
或者-force_load
是需要链接类别连接标志已经被固定在LLVM。该修复程序作为 LLVM 2.9 的一部分发布 包含该修复程序的第一个 Xcode 版本是随 LLVM 3.0 一起发布的 Xcode 4.2。使用 Xcode 4.2 时不再需要上述修复。-ObjC
链接 ObjC 二进制文件时仍然需要该标志
回答by Matt
I just had this same problem but adding any combination of the described flags (-ObjC, -all_load, -force_load) did not work.
我刚刚遇到了同样的问题,但是添加所描述标志(-ObjC、-all_load、-force_load)的任何组合都不起作用。
It turned out that I had not checked the box "Add to Target" when adding the files to the project. I removed the files from the project and added them again, this time making sure that that box was checked. This fixed the problem.
事实证明,在将文件添加到项目时,我没有选中“添加到目标”框。我从项目中删除了文件并再次添加,这次确保选中该框。这解决了问题。
回答by Jon Lundy
I ran into this problem recently. I was unable to get the -all_load to work, when I noticed that another category I had DID work. I was lazy for this category and included it in with another file.
我最近遇到了这个问题。当我注意到另一个类别我有 DID 工作时,我无法让 -all_load 工作。我对这个类别很懒惰,并将它包含在另一个文件中。
I eventually created a dummy class (no methods, instance variables) and included the implementation of my categories in the .m file for that dummy class. After doing this my categories started working even after I removed the -all_load flag.
我最终创建了一个虚拟类(没有方法、实例变量),并将我的类别的实现包含在该虚拟类的 .m 文件中。完成此操作后,即使删除了 -all_load 标志,我的类别也开始工作。
This was on iPhone OS 3.1.3.
这是在 iPhone OS 3.1.3 上。
This certainly is not the RIGHT way to fix it, but it seemed to work.
这当然不是修复它的正确方法,但它似乎有效。
Full sample code is on my blogfor my (trivial) categories.
完整的示例代码在我的博客上,用于我的(琐碎)类别。
回答by Chris Miles
I had the same problem with Categories in my static library. In my case, "-all_load" didn't help as it caused loads of build errors (my static library is a wrapper around another private C/C++ lib).
我的静态库中的 Categories 也有同样的问题。就我而言,“-all_load”没有帮助,因为它导致了大量构建错误(我的静态库是另一个私有 C/C++ 库的包装器)。
I solved it by a hack suggested at http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.htmlwhich simply involved adding a dummy (empty) class definition to the category files. Using this hack, I kept "-ObjC" but dropped "-all_load" in the application linker settings and it worked fine on the device.
我通过http://iphonedevelopmentexperiences.blogspot.com/2010/03/categories-in-static-library.html建议的 hack 解决了它,它只涉及向类别文件添加一个虚拟(空)类定义。使用这个 hack,我保留了“-ObjC”,但在应用程序链接器设置中删除了“-all_load”,它在设备上运行良好。
回答by Chris Miles
In the past I was able to force linkage of the category with -u .objc_category_name_UIView_Extensions, but with the 3.0 dev environment that's broken and the only option seems to be -all_load.
在过去,我能够强制使用 -u .objc_category_name_UIView_Extensions 链接类别,但是 3.0 开发环境已损坏,唯一的选项似乎是 -all_load。