Unrecognized selector sent to class runtime error - ios

I am using a third party framework containing a category on NSData and having a static method dataUsingBase64String: in it.
The framework got linked fine and code builds successfully. But I am getting unrecognized selector sent to class runtime error when this method gets called.
I have also tried adding -ObjC,-all_load flags in OTHER_LINKER_FLAGS of XCode with no luck..

I guess your library is statically linked. A common problem in that is categories are not included or linked. You additionally need to add -all_load to the Other Linker Flags of the target which is using your static library.
Also check the below answers similar to your problem
Answer 1 - NSData Unrecognized selector sent to class
Answer 2 - Objective-C Category Causing unrecognized selector
Answer 3 - "unrecognized selector sent to instance" to a static library despite ObjC flag
I hope this helps

Note: I needed to add framework in this way,
Framework Search Paths instead of adding frameworks to "Linked Frameworks and Libraries" section
Here, somehow the framework was not loaded even after adding-Objc or -all_load.
Finally, -framework in OTHER_LINKER_FLAGS did the trick for me.
Something about it from manpage,
-framework name[,suffix]
This option tells the linker to search for `name.frame-
work/name' the framework search path. If the optional suffix
is specified the framework is first searched for the name
with the suffix and then without (e.g. look for `name.frame-
work/name_suffix' first, if not there try `name.frame-
work/name').

If -Objc does not take effect, you can try to delete your Category from the project and drag it to the project again, and check Target membership.

Related

iOS Build settings Other Linker Flags

I have a project which is written in swift and i was trying to integrate GoogleSignIn in my project when the program kept crashing saying:
-[__NSDictionaryI gtm_httpArgumentsString]: unrecognized selector sent to instance
Then I googled the problem and found a solution to add -ObjC Other Linker Flag to my build settings.
So my question is what does this step does and how did it fix the problem.
Can anyone please explain what is Other Linker Flag and what it does?
For your explanations about the "Other Linker Flag" and why fix the problem like this see :
https://developer.apple.com/library/mac/qa/qa1490/_index.html
This flag causes the linker to load every object file in the library that defines an Objective-C class or category. While this option will typically result in a larger executable (due to additional object code loaded into the application), it will allow the successful creation of effective Objective-C static libraries that contain categories on existing classes.

Reason to include "-ObjC" in Xcode

We include "-ObjC"in other linker flags of project settings in Xcode if we include any external libraries or frameworks can any one tell me what is the reason for it and what it does if we include it.
Thanks in Advance..
It's explained pretty well in Apple's QA1490.
Key excerpts:
Objective-C does not define linker symbols for each function (or
method, in Objective-C) - instead, linker symbols are only generated
for each class.
...
To resolve this issue, the target linking against the static library
must pass the -ObjC option to the linker. This flag causes the linker
to load every object file in the library that defines an Objective-C
class or category
Categories are most known use case for this flag (as Apple's QA1490 explains), but they are not the only reason why this flag is needed.
Since Objective-C is a dynamic language which makes things like NSClassFromString() possible, the standard behaviour of C linker of including only actually used symbols (and throwing away all others) does not work, because there is no way to find out whether some symbols are actually used in some indirect ways like concatenating strings then calling NSSelectorFromString or NSClassFromString.
Consider xib/nib files for example: they don't participate in linking stage, yet they may instantiate library classes which are not referred by anything but this nib file. If linker threw away those classes as unused, the nib couldn't load and work properly.
The only way to ensure nothing is lost is to include every Obj-C class from a library at link time, and this flag does that.
-ObjC linker flag causes the linker to load ever object file in the library that defines an Objective-C class or category.
Why to use -ObjC linker flag - Apple Documentation?

Problems in adding core plot frame work with existing project in Workspace

I want to use core plot in my project to display bar&scatter plots.Before that I made a prototype project where I was successful in plotting those two. But when I tried to include it into my project faced some problems.
1) My project has a static library so according to the https://code.google.com/p/core-plot/wiki/UsingCorePlotInApplications, I added coreplot-cocoatouch.xcodeproj added too as a static library to my project and i set linker flags -ObjC as well for my app project then compiler throws a Mac linker error "Command /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/usr/bin/llvm-gcc-4.2 failed with exit code 1"
2) If I did not include -ObjC it throws error "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString sizeWithTextStyle:]: unrecognized selector sent to instance "
I am not able to find where am I doing wrong.Is it the problem with ARC because my project doesnt use ARC but as per some forums, I found we can use non ARC and ARC libraries in a single workspace.
I tried with CorePlot versions 1.3 and 1.4 & using Xcode 4.5, are these two arc or not.
Any help is appreciated.
Thanks in Advance.
1 Possible reason may be that there are 2 different versions (duplicate) of Core-Plot Exists in your build directory.. or you have #import .m class instead of .h in your code.. sometimes same thing happens if you have 2 different classes with same name exists in your code.. Also do try cleaning your build directory and check again.
Use the Core Plot dependent project or the pre-built static library, not both.
The -ObjC linker flag is required. You also need the -all_load linker flag. That error message means that one of the category methods added by Core Plot did not load at runtime; the -all_load flag tells the linker to make sure the app knows to load those methods, too.

SDWebImage : setImageWithURL fails when used to set image of a UITableViewCell

When call setImageWithURL, it fails with following,
[UIImageView setImageWithURL:placeholderImage:]: unrecognized selector sent to instance 0x149a20 2011-12-14 18:11:38.060 [781:707]
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[UIImageView
setImageWithURL:placeholderImage:]: unrecognized selector sent to
instance 0x149a20'
I can confirm I have included SDWebImage project and required headers correctly as I can use the SDWebImageManager successfully.
Following is the code where I called the UIImageView category method setImageWithURL
NSURL* url = [NSURL URLWithString:#"www.abc.com/abc.png"];
[cell.imageView setImageWithURL:url placeholderImage:[UIImage imageNamed:#"abc.png"]];
As per:
linking objective-c categories in a static library
Due to a linker bug in XCode, you need to set the 'Other Linker Flags' setting your build target. Setting the flag as follows should eliminate this error.
-force_load ${BUILT_PRODUCTS_DIR}/libSDWebImage.a
This will solve the problem: Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag:
If anyone, like me, still has problems after seeing all the other answers here (e.g. force_load or load_all) even after following all the proper installation instructions, here is what I have learnt after doing some search online:
This problem only happens when you use iPhone 5S or the 64-bit simulator
This is a problem with libwebp
The solution to this problem:
Only do this if you don't need the 64-bit processor for your app (too new to iOS programming to know if this sentence is valid)
Go to build settings > Architecture
Under Architecture, select Standard architectures (armv7,armv7s)
Under Build Active Architecture Only, make sure it is Yes for both Debug and Release
My source: https://github.com/rs/SDWebImage/issues/494
I hope this helps those who, like me, found this while trying to solve your problem =)
I ended up inserting all the .h and .m files into my project and then it worked fine. I got the same error when I only included the .a and .h files.
In the SDWebImage docs, it says that you have to set "Other Linker Flags" to -ObjC. This did not work for me. Instead, I set it to -all_load. I also had to remove -ObjC. The explanation for what is going on can be found here:
http://developer.apple.com/library/mac/#qa/qa1490/_index.html
It also explains why -ObjC fails: "Important: For 64-bit and iPhone OS applications, there is a linker bug that prevents -ObjC from loading objects files from static libraries that contain only categories and no classes. The workaround is to use the f-all_load or -force_load flags"
Using -all_load increases the size of the executable. You can use -force_load to mitigate this somewhat. For SDWebImage 2.7.3, I did this by setting the following in "Other Linker Flags" in the Build Settings: "-load_all $(SRCROOT)/SDWebImage.framework/SDWebImage". Linking to libSDWebImage[ARC].a which is what some sources advise, didn't work for me.
Incidentally, in Xcode 4.4, it seems you have to do a slow double-click in order to change build settings properly. Doing a normal double-click shows the completely screwed up and non-working pop-up.
Solved the same problem adding the libSDWebImage.a to Build Phases > Link Binary with Libraries.
If you read the document here https://github.com/rs/SDWebImage at the bottom there is a download link with the CORRECT files to download. Following that example it works perfectly.
The mistake I made, and seemingly others to, is I downloaded the github project and tried using that.
Everything started to work for me once I linked "ImageIO.framework" to my main project.
You can also set 'Other Linker Flags' to -all_load. This solves the problem where an external framework (such as the filepicker framework) requires linking against SDWebImage.
-force_load is not fix fundamental problem (when achiveing problem happens)
to fix this linking problem..
edit scheme for SDWebImage,
run scheme set for release
run (with device)
libSDWebImage.a will be generated in release-iphoneos directory.
set target->BuildPhase->link Binarywithlibrary .. add this lib.
Done..
Make sure your compiled files have UIIMageView+AFNetworking.m in case you're using AFNetworking framework.
You need to add the libSDWebImage.a in your linked binaries, also check for other linker flags, it should be -ObjC
Checkout your choice when you pull files of SDWebimages into Xcode, do mark the "create groups" in added folders, and do not mark the "create folder references".
Mark exactly as the picture:

linking objective-c categories in a static library

I am developing a plugin for an iOS application. I am compiling it into a .a file which is then used by the main xcode project.
So far I have create a category of the UIDevice class in this library. When I run the main project using this library it crashes due to an unrecognized selector
-[UIDevice platform]: unrecognized selector sent to instance
platform is one of the fuinctions I added via the category.
So I thought it wasn't linking those functions at all and added a c function to the same file as the UIDevice category then called it from my code .
This time the main project ran fine... So I thought maybe it was something else i did and removed the C function. But lo and behold it crashed again due to unrecognized selector..
My questions:
Why does xcode ignore the category definition unless I call a function declared in the same file?
Is there an xcode setting i can change to make it include these methods from the UIDevice category regardless of whether I call a function from that file or not?
cheers
Check out Building Objective-C static libraries with categories:
Objective-C does not define linker symbols for each function (or
method, in Objective-C) - instead, linker symbols are only generated
for each class. If you extend a pre-existing class with categories,
the linker does not know to associate the object code of the core
class implementation and the category implementation. This prevents
objects created in the resulting application from responding to a
selector that is defined in the category.
To resolve this issue, the target linking against the static library
must pass the -ObjC option to the linker. This flag causes the linker
to load every object file in the library that defines an Objective-C
class or category. While this option will typically result in a larger
executable (due to additional object code loaded into the
application), it will allow the successful creation of effective
Objective-C static libraries that contain categories on existing
classes.
Important: For 64-bit and iPhone OS applications, there is a
linker bug that prevents -ObjC from loading objects files from static
libraries that contain only categories and no classes. The workaround
is to use the -all_load or -force_load flags.
Source: #albertamg (linking objective-c categories in a static library)
I have had the same problem. A method defined in a category defined in a subproject resulted in an unrecognized selector exception. (In fact, this manifested as inability to specify an UILabel subclass in Interface Builder; the XIB contained the class shown in IB (UILabel or UIView, depending on what I dragged there), rather than the class that I have typed in, and that looked as a weird XCode bug.)
The solution that worked for me has been to use -force_load:
In the left-hand panel, select your main project (the root item). On the right, you will see PROJECT and TARGETS. Select TARGETS.
Go to "Build Settings"(in the upper bar) -- "Linking" -- "Other linker flags" and, assuming your subproject is called XXXXX, add
-force_load ${BUILT_PRODUCTS_DIR}/libXXXXX.a
there (the item has two subitems, Debug and Release, but you click on this compound item so that if affects both Debug and Release).
Note that -force_load works for a single library, and you may need to specify a separate -force_load for each subproject library.
I had this issue and spent near 1 hour to resolve it. Thanks god! it's been done. Methods which are defined should be static type!

Resources