Can GC Application be linked to an ARC Framework? - objective-c

I have an application that uses GC for memory management and a framework that does automatic reference counting. When I try to build that, I get this error:
Linked dylibs built for retain/release but object files built for GC-only for architecture x86_64
Is there a correct way to use the ARC framework in this GC application without changing it? I remember to read that ARC code seemslessly works with non-ARC code, but I only find the per-file compiler switch (-fobjc-arc).

No. ARC code works with manual retain-release code, but not with GC code. A framework built for garbage collection only will not work with either manual retain-release code or ARC; a framework built in GC-optional mode will work the same with both.

Related

Using autorelease requires disable ARC

Hello I am completely new to Apple development
I used this code in my project
https://github.com/vladinecko/accordion-uitableview/tree/master/AccordionTableView
, project releases the memory itself using autorelease
What made ​​me disable the ARC
Because ARC does not allow the use of autorelease
My question is whether to delete the autorelease from the code
And use ARC or i can not do it and I need to have to release the memory for myself
You could leave the code as-is—you can compile some files using ARC and others not, but that’s going to be messy and hard to maintain.
What I’d recommend doing is running Xcode’s ARC-ifying on the code, to get rid of retain and release and autorelease.
In Xcode 5, look under the “Edit” menu for “Refactor”, and select “Convert to ObjC ARC”.
Apparently AccordionTableView does not use ARC, whereas in your project you are using it.
So you have three options
Switch off ARC only for the separate compilation units, which are from AccordionTableView
Adapt the code snippet from AccordionTableView project with ARC guidelines
Switch your own project to not use ARC
First, being new to Objective-C development you need to learn how memory management works. Google for "Apple memory management" and you should find relevant documents.
Before ARC, people did memory management by hand. With ARC, ARC does it for you. The exact same memory management operations should happen, except that with ARC you have less programmer work, and chances to get it right are better.
You have two choices: Either turn ARC off for individual files. This is done in Xcode / target settings / Build phases / Compile sources by adding -fno-objc-arc to the build settings for individual files where you don't want to use ARC. If you use the same files in different projects, you have to do this in every target.
The other choice is to convert the files to ARC. Let the compiler run, remove offending memory management code, which is mostly retain / release / autorelease. If the code uses CoreFoundation functions, then you really need to understand memory management, just hope it doesn't. Use "Analyze" to let the compiler check very carefully that everything is fine.

What is the correct way to fail at compile-time if ARC is off?

I'm working on some Objective-C code I expect to spin off into a library or at least share with some other people. It requires ARC to use, and if ARC is not enabled, it will leak memory.
What is the correct way to make the code fail to compile if ARC is turned off?
You can check for ARC at compile time with
#if __has_feature(objc_arc)
I think a cleaner approach would be to compile the library as a static library. As ARC will incorporate the release calls according to the rules into the compiled library, it doesnt matter from that point on, if the project it is added to is ARC or MRC — so no hassle for the library user.

Do i need to remove all memory management methods in ARC-enabled project?

my app is developed with ARC disabled from the beginning, now i decided to take advantage of ARC techniques, when i try to convert the project to ARC i keep getting errors wherever release autorelease methods are exist, does that mean i have to dig into my project and get rid of any methods related to memory management? thanks
Yes, you are not allowed to use release, retain, or autorelease in ARC code. If it's too much of a hassle, you can disable ARC on a per-file basis as described here: How can I disable ARC for a single file in a project?
There are a lot of good references on the web that deal with automatic reference counting, e.g.
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
or
http://www.mikeash.com/pyblog/friday-qa-2011-09-30-automatic-reference-counting.html

Tool for transitioning to ARC

I want to transition my App to ARC. I can change Objective-C Automatic Reference Counting to YES but that does not automatically remove releases retains etc.
The Transitioning to ARC Release Notes states:
Xcode has a new tool that automates the mechanical parts of the ARC conversion (such as removing retain and release calls) and helps you to fix issues the migrator can’t handle automatically. The migration tool converts all files in a project to use ARC. You can also choose to use ARC on a per-file basis if it’s more convenient for you to use manual reference counting for some files.
How do I invoke this tool in Xcode?
Oh man I just found it:
Convert > To Objective-C ARC
I checked in Xcode's help first where I could not find it.

Mixing garbage collected framework with normal code

I know my way around Objective-C and I have experience with garbage collection from .NET, although I never used it in objective-c. I write my code without using it.
Now I'm thinkig about using one of the frameworks (Blocks) which is available as GC-only. My question is - can I still use the framework without any changes to my current non-GC code and without using GC myself?
A process is either GC or non-GC. That is, all Objective-C will either always be GC'd or will never be GC'd. There is no mixing of the two memory models in a single process. You cannot mix a GC only framework with a non-GC only framework.
When building a framework, you can set GC to "supported" at which point in time the framework could be used in either a GC'd or a non-GC'd process. However, you will have to maintain correctness for both running environments separately.
What is this "Blocks" framework to which you refer? If you are talking about Blocks, the language feature shipped in Snow Leopard's Objective-C, then it works just fine under both GC and non-GC.
As stated in the garbage collection programming guide, "Code compiled as GC Required is presumed to not use traditional Cocoa retain/release methods and may not be loaded into an application that is not running with garbage collection enabled."
So no, unfortunately. But how much work it would be to adopt garbage collection depends on your app. You might try testing to see if it looks like a big project. (It often is, but sometimes it's not so bad.)
In project settings, you can compile with GC supported (NOT required) and they should mix just fine. Compiling with GC supported but not required should allow retain/release to work alongside GC
If you can't compile the project with GC supported, then you'll be in trouble.
EDIT: To clarify: If you compile your project with GC required (-fobjc-gc-only) your retain/release code will be ignored. If you compile without any regard for GC, you can't use the GC framework. However, if you compile with GC supported (-fobjc-gc), your retain/release code will function as needed, and the GC framework will also work.
EDIT: To further clarify (I'm really tired today): If you include a GC-only framework, you have to compile with -fobjc-gc or -fobjc-gc-only and run with garbage collection, in which case your retain/release statements will indeed be no-ops. However, if you compile with -fobjc-gc-only and try to include a framework that is not build with any GC support, you'll have issues. Whereas my understanding is if you compile with -fobjc-gc, you can include a GC-only framework as well as a non-GC framework. From the docs I linked above:
Code compiled as GC Supported is
presumed to also contain traditional
retain/release method logic and can be
loaded into any application.
So if you wanted your Framework to play nice with anything, you'd be better served to compile with -fobjc-gc instead of -fobjc-gc-only.
Apparently I was having a hard time getting my thoughts to the keyboard yesterday. According to the docs:
-fobjc-gc-only This means that only GC logic is present. Code compiled as GC
Required is presumed to not use
traditional Cocoa retain/release
methods and may not be loaded into an
application that is not running with
garbage collection enabled.
So if you build your framework with GC Required, you can't load it into a non-GC-enabled application.
Also according to the docs:
-fobjc-gc This means that both GC and retain/release logic is present. Code
compiled as GC Supported is presumed
to also contain traditional
retain/release method logic and can be
loaded into any application.
So while the burden is on the developer to include retain/release logic in a project that is compiled GC Supported, this allows a framework to be loaded in any application.
I apologize for my unclear rambling yesterday. I was running on 3 hours sleep and trying to do several things at once. Never a good idea.