Reason to include "-ObjC" in Xcode - ios

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?

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.

Category method symbols in static library aren't visible in main executable

We're converting a project to 64 bit and having some trouble with unrecognized selectors at runtime.
It's due to some category functions that are defined in a static library not being visible from the main executable. We have the -ObjC linker flag set and I've even tried using -force_load with the static library path that has these category functions defined but no matter what they're still not found at runtime.
Check with -all_load linker flag.

How do I solve class name conflicts when creating an iOS framework?

I am writing an iOS framework Foo that depends on a static third-party library Lib and have problems getting the linking right.
If Foo was a static library, I would not link it against Lib, and only link the master project against both of them. But this approach does not seem to work with a framework: the linker complains about missing symbols from Lib.
So I took the other approach and linked Foo against Lib. Now the linker is happy, but there’s an obvious catch: if the master project uses Lib for its own reasons and links both against Foo and Lib, I get duplicate symbols:
Class <Something> is implemented in both <Here> and <There>.
One of the two will be used. Which one is undefined.
I know I can stop linking the app against Lib and all will be fine, but I’d like to get things right. How?
I was able to get this working for a framework, though the docs say it should work for a static library as well.
What I did is link the master project against both Foo and Lib as you say. Now Foo has "missing symbol" errors. Select the Foo target and go to Other Linker Flags. Add -weak_framework Lib and presto! the linker will stop complaining. The duplicate symbol runtime errors go away.
According to the docs:
The -weak_framework option tells the linker to weakly link all symbols in the named framework. If you need to link to a library instead of a framework, you can use the -weak_library linker command instead

Linker flags for iOS with Xcode

Where can I find documentation on the compiler flags and linker flags that we can specify for our iOS projects in Xcode?
The present reason I want to read more on the possible flags in the first place is that the Google Admob SDK says we MUST set the linker -Objc flag, whereas Facebook SDK suggests NOT setting it for smaller binaries. So, I was wondering, can we set Objc for a particular library (google admob in this case) and have it unset for another library (facebook)? I expected to be able to find a man page or some other doc about what the compiler and linker options are in the first place, and then zoom in on Objc. There's tons of documentation and stackoverflow posts etc. on how to set linker flags in Xcode. What's lacking is a listing of possible linker flags we can set, and what they each mean.
Surprisingly, googling around made me quite confused, as there's stuff on clang, llvm, llvm-gcc, etc., and LLVM site lists a number of llvm commands but I don't see -Objc listed in any of the corresponding pages. Apart from the question of whether the compiler and linker are clang or llvm, or whatever they're called, is there a place we could go to in order to read documentation on whatever Xcode is currently using by default for compiling and linking iOS projects? (say, both Xcode 4.6 and Xcode 5.0.2, in case there are different doc sets?) Thanks!
You can try man 1 ld.
For the -ObjC flag in particular the description is:
-ObjC Loads all members of static archive libraries that
implement an Objective-C class or category.
EDIT
For your other question about the AdMob SDK and the Facebook SDK, I would suggest to add the -ObjC to the linker flags and take a look at this article which explains why. Basically Facebook suggests not to use it, because your executable will end up being larger due to additional object code loaded into your binary.
I had this problem when I put a function into my .hpp file.
void logError(char const* szError)
{
...
}
I had to add in the inline to make it work.
inline void logError(char const* szError)
{
...
}
Even better don't define your functions inside your headers.

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