Since I'm currently in the process of learning development in Objective-C I intended to use the newest tools provided whereever possible (except for the beta-quality ones) - that includes Automatic Reference Counting. ARC is intended to make life easier for developers by automatically inserting memory-management related instructions during compile time.
Automatic Reference Counting implements automatic memory management for Objective-C objects and blocks, freeing the programmer from the need to explicitly insert retains and releases.
You enable the technology when creating a new project, a compiler flag gets set (
-fobjc-arc if you're curious), done. Afterwards you develop according to slightly changed criteria, but generally don't have to worry about the previously Obj-C typical 'retain', 'release' and 'autorelease' instructions. This is work the Clang compiler does for you when building your project.
There are even tools to help you migrate your previous projects to ARC. You can even use them to migrate external code to ARC. This is precisely where my problems began.
I intended to write a simple cache file listing which files have already been processed and which are to be processed again due to changes and wanted to implement that using the filename and a hash value for that. Since I was initially too lazy to reach down into C using Common Crypto I intended to use a a class provided by Matt Gallagher in order to save time and focus on my project instead of fighting with C.
The first thing I noticed was that the code was already a bit older and therefor written before the advent of ARC. Well, no problem, let's just run the 'Migrate to ARC' tool. But little is ever as simple as just running a conversation tool on existing code. While the converter worked pretty well and it's suggestions were perfect for the intended class, not selecting my existing, already ARCified classes set their compiler-flag to
-fno-objc-arc 1. I wondered why I had to manually type 'strong' when declaring properties after that and why Xcode suggested that it used 'assign' when not specifying 'strong' even though that's a non-ARC convention.
Today I ran the 'Analyze' build setting and fixed some leaks. In the process I also got a warning about a potential leak that I just couldn't find. I seemed to do everything right and still got a warning about the leak:
main.m:92:3: Object leaked: object allocated and stored into 'cachedFiles' is not referenced later in this execution path and has a retain count of +1
After a lot of swearing, frantically searching for answers and annoying others, my girlfriend suggested that I may have lost ARC somewhere. But I checked the Build Settings for the project and ARC was on. I did a quick test by creating a new Xcode project file, copied files over and ran 'Analyze' again. Sure enough, there were no warnings at all. More swearing ensured. Finally I stumbled across a helpful post on StackOverflow and put both project files in FileMerge. The ARC flags were spotted.
To fix the problem I opened the project in Xcode, went to the build target, the tab Build Phases, Compiles Sources and removed offending compiler flags from the affected files.
- Why would I want to convert my already ARCified classes to ARC? What's the point of setting that flag when the original project setting already was 'enable ARC'? ↩