Memory Leaks when Working with Address Book Contacts in iOS6 - objective-c

I'm using ARC, and my application compiles and works without crashing. However, when I run an Analyze build, I am seeing these warnings. I come from PHP and JavaScript so naturally I have no idea what to do to fix this stuff. Can anyone help me out?

ARC needs some help when dealing with Core Foundation. Try this:
NSArray *linkedPeople = (__bridge_transfer NSArray *)ABPersonCopyArrayOfAllLinkedPeople(person);
and
NSDictionary *personDictionary = (__bridge_transfer NSDictionary *)(ABMultiValueCopyValueAtIndex(addressFromPerson, 0));
__bridge_transfer tells ARC that a non-Objective-C (i.e., Core Foundation) pointer is being moved to an Objective-C pointer, and it allows ARC to take ownership of the object for memory management purposes. CF functions with the word "copy" in them produce an object reference with a +1 reference count. If you don't explicitly call CFRelease() on the object later, then it will leak. Using __bridge_transfer, however, lets ARC do this for you.
(Note: I didn't test this, but I believe those are the issues that the static analyzer is complaining about.)

Yes, you can use:
NSArray *linkedPeople = (__bridge_transfer NSArray *)ABPersonCopyArrayOfAllLinkedPeople(person);
But Apple now recommends using:
NSArray *linkedPeople = CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
It does the same thing, but Apple recommends you use the latter.
See WWDC 2012 session 405, 37:33 into the presentation.

So! Even though you're using Automatic Reference Counting (ARC), it's still a good idea to read up on Objective-C Memory Management:
http://longweekendmobile.com/2011/09/07/objc-automatic-reference-counting-in-xcode-explained/
But, for your specific problem:
Generally, when you see a C method in the Apple frameworks that has the word Copy in it, you're taking ownership of that Core Foundation type and you need to release it. When you want to release that type, just use:
CFRelease(addressFromPerson)
That's the first issue. Your screenshot cuts off the second error so I'm only speculating, but I think you also need to release your NSDictionary *personDictionary. Similarly:
CFRelease(personDictionary)
Note that you also need to manage the memory for linkedPeople
Normally ARC will take care of memory management for you, but when working with Core Foundation types, you still need to clean up after yourself.
I would strongly recommend you check out these great resources on memory management with ARC, particularly when dealing with CF types and toll-free bridging:
http://www.joergjacobsen.com/blog/2011/10/05/managing-toll-free-bridging-in-an-arced-environment/
http://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html

Related

Do I need to use autorelease on object which created not using alloc init? [duplicate]

I'm just beginning to have a look at Objective-C and Cocoa with a view to playing with the iPhone SDK. I'm reasonably comfortable with C's malloc and free concept, but Cocoa's references counting scheme has me rather confused. I'm told it's very elegant once you understand it, but I'm just not over the hump yet.
How do release, retain and autorelease work and what are the conventions about their use?
(Or failing that, what did you read which helped you get it?)
Let's start with retain and release; autorelease is really just a special case once you understand the basic concepts.
In Cocoa, each object keeps track of how many times it is being referenced (specifically, the NSObject base class implements this). By calling retain on an object, you are telling it that you want to up its reference count by one. By calling release, you tell the object you are letting go of it, and its reference count is decremented. If, after calling release, the reference count is now zero, then that object's memory is freed by the system.
The basic way this differs from malloc and free is that any given object doesn't need to worry about other parts of the system crashing because you've freed memory they were using. Assuming everyone is playing along and retaining/releasing according to the rules, when one piece of code retains and then releases the object, any other piece of code also referencing the object will be unaffected.
What can sometimes be confusing is knowing the circumstances under which you should call retain and release. My general rule of thumb is that if I want to hang on to an object for some length of time (if it's a member variable in a class, for instance), then I need to make sure the object's reference count knows about me. As described above, an object's reference count is incremented by calling retain. By convention, it is also incremented (set to 1, really) when the object is created with an "init" method. In either of these cases, it is my responsibility to call release on the object when I'm done with it. If I don't, there will be a memory leak.
Example of object creation:
NSString* s = [[NSString alloc] init]; // Ref count is 1
[s retain]; // Ref count is 2 - silly
// to do this after init
[s release]; // Ref count is back to 1
[s release]; // Ref count is 0, object is freed
Now for autorelease. Autorelease is used as a convenient (and sometimes necessary) way to tell the system to free this object up after a little while. From a plumbing perspective, when autorelease is called, the current thread's NSAutoreleasePool is alerted of the call. The NSAutoreleasePool now knows that once it gets an opportunity (after the current iteration of the event loop), it can call release on the object. From our perspective as programmers, it takes care of calling release for us, so we don't have to (and in fact, we shouldn't).
What's important to note is that (again, by convention) all object creation class methods return an autoreleased object. For example, in the following example, the variable "s" has a reference count of 1, but after the event loop completes, it will be destroyed.
NSString* s = [NSString stringWithString:#"Hello World"];
If you want to hang onto that string, you'd need to call retain explicitly, and then explicitly release it when you're done.
Consider the following (very contrived) bit of code, and you'll see a situation where autorelease is required:
- (NSString*)createHelloWorldString
{
NSString* s = [[NSString alloc] initWithString:#"Hello World"];
// Now what? We want to return s, but we've upped its reference count.
// The caller shouldn't be responsible for releasing it, since we're the
// ones that created it. If we call release, however, the reference
// count will hit zero and bad memory will be returned to the caller.
// The answer is to call autorelease before returning the string. By
// explicitly calling autorelease, we pass the responsibility for
// releasing the string on to the thread's NSAutoreleasePool, which will
// happen at some later time. The consequence is that the returned string
// will still be valid for the caller of this function.
return [s autorelease];
}
I realize all of this is a bit confusing - at some point, though, it will click. Here are a few references to get you going:
Apple's introduction to memory management.
Cocoa Programming for Mac OS X (4th Edition), by Aaron Hillegas - a very well written book with lots of great examples. It reads like a tutorial.
If you're truly diving in, you could head to Big Nerd Ranch. This is a training facility run by Aaron Hillegas - the author of the book mentioned above. I attended the Intro to Cocoa course there several years ago, and it was a great way to learn.
If you understand the process of retain/release then there are two golden rules that are "duh" obvious to established Cocoa programmers, but unfortunately are rarely spelled out this clearly for newcomers.
If a function which returns an object has alloc, create or copy in its name then the object is yours. You must call [object release] when you are finished with it. Or CFRelease(object), if it's a Core-Foundation object.
If it does NOT have one of these words in its name then the object belongs to someone else. You must call [object retain] if you wish to keep the object after the end of your function.
You would be well served to also follow this convention in functions you create yourself.
(Nitpickers: Yes, there are unfortunately a few API calls that are exceptions to these rules but they are rare).
If you're writing code for the desktop and you can target Mac OS X 10.5, you should at least look into using Objective-C garbage collection. It really will simplify most of your development — that's why Apple put all the effort into creating it in the first place, and making it perform well.
As for the memory management rules when not using GC:
If you create a new object using +alloc/+allocWithZone:, +new, -copy or -mutableCopy or if you -retain an object, you are taking ownership of it and must ensure it is sent -release.
If you receive an object in any other way, you are not the owner of it and should not ensure it is sent -release.
If you want to make sure an object is sent -release you can either send that yourself, or you can send the object -autorelease and the current autorelease pool will send it -release (once per received -autorelease) when the pool is drained.
Typically -autorelease is used as a way of ensuring that objects live for the length of the current event, but are cleaned up afterwards, as there is an autorelease pool that surrounds Cocoa's event processing. In Cocoa, it is far more common to return objects to a caller that are autoreleased than it is to return objets that the caller itself needs to release.
Objective-C uses Reference Counting, which means each Object has a reference count. When an object is created, it has a reference count of "1". Simply speaking, when an object is referred to (ie, stored somewhere), it gets "retained" which means its reference count is increased by one. When an object is no longer needed, it is "released" which means its reference count is decreased by one.
When an object's reference count is 0, the object is freed. This is basic reference counting.
For some languages, references are automatically increased and decreased, but objective-c is not one of those languages. Thus the programmer is responsible for retaining and releasing.
A typical way to write a method is:
id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;
The problem of needing to remember to release any acquired resources inside of code is both tedious and error-prone. Objective-C introduces another concept aimed at making this much easier: Autorelease Pools. Autorelease pools are special objects that are installed on each thread. They are a fairly simple class, if you look up NSAutoreleasePool.
When an object gets an "autorelease" message sent to it, the object will look for any autorelease pools sitting on the stack for this current thread. It will add the object to the list as an object to send a "release" message to at some point in the future, which is generally when the pool itself is released.
Taking the code above, you can rewrite it to be shorter and easier to read by saying:
id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;
Because the object is autoreleased, we no longer need to explicitly call "release" on it. This is because we know some autorelease pool will do it for us later.
Hopefully this helps. The Wikipedia article is pretty good about reference counting. More information about autorelease pools can be found here. Also note that if you are building for Mac OS X 10.5 and later, you can tell Xcode to build with garbage collection enabled, allowing you to completely ignore retain/release/autorelease.
Joshua (#6591) - The Garbage collection stuff in Mac OS X 10.5 seems pretty cool, but isn't available for the iPhone (or if you want your app to run on pre-10.5 versions of Mac OS X).
Also, if you're writing a library or something that might be reused, using the GC mode locks anyone using the code into also using the GC mode, so as I understand it, anyone trying to write widely reusable code tends to go for managing memory manually.
As ever, when people start trying to re-word the reference material they almost invariably get something wrong or provide an incomplete description.
Apple provides a complete description of Cocoa's memory management system in Memory Management Programming Guide for Cocoa, at the end of which there is a brief but accurate summary of the Memory Management Rules.
I'll not add to the specific of retain/release other than you might want to think about dropping $50 and getting the Hillegass book, but I would strongly suggest getting into using the Instruments tools very early in the development of your application (even your first one!). To do so, Run->Start with performance tools. I'd start with Leaks which is just one of many of the instruments available but will help to show you when you've forgot to release. It's quit daunting how much information you'll be presented with. But check out this tutorial to get up and going fast:
COCOA TUTORIAL: FIXING MEMORY LEAKS WITH INSTRUMENTS
Actually trying to force leaks might be a better way of, in turn, learning how to prevent them! Good luck ;)
Matt Dillard wrote:
return [[s autorelease] release];
Autorelease does not retain the object. Autorelease simply puts it in queue to be released later. You do not want to have a release statement there.
My usual collection of Cocoa memory management articles:
cocoa memory management
There's a free screencast available from the iDeveloperTV Network
Memory Management in Objective-C
NilObject's answer is a good start. Here's some supplemental info pertaining to manual memory management (required on the iPhone).
If you personally alloc/init an object, it comes with a reference count of 1. You are responsible for cleaning up after it when it's no longer needed, either by calling [foo release] or [foo autorelease]. release cleans it up right away, whereas autorelease adds the object to the autorelease pool, which will automatically release it at a later time.
autorelease is primarily for when you have a method that needs to return the object in question (so you can't manually release it, else you'll be returning a nil object) but you don't want to hold on to it, either.
If you acquire an object where you did not call alloc/init to get it -- for example:
foo = [NSString stringWithString:#"hello"];
but you want to hang on to this object, you need to call [foo retain]. Otherwise, it's possible it will get autoreleased and you'll be holding on to a nil reference (as it would in the above stringWithString example). When you no longer need it, call [foo release].
The answers above give clear restatements of what the documentation says; the problem most new people run into is the undocumented cases. For example:
Autorelease: docs say it will trigger a release "at some point in the future." WHEN?! Basically, you can count on the object being around until you exit your code back into the system event loop. The system MAY release the object any time after the current event cycle. (I think Matt said that, earlier.)
Static strings: NSString *foo = #"bar"; -- do you have to retain or release that? No. How about
-(void)getBar {
return #"bar";
}
...
NSString *foo = [self getBar]; // still no need to retain or release
The Creation Rule: If you created it, you own it, and are expected to release it.
In general, the way new Cocoa programmers get messed up is by not understanding which routines return an object with a retainCount > 0.
Here is a snippet from Very Simple Rules For Memory Management In Cocoa:
Retention Count rules
Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.
Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased.
Implement a -dealloc method to release the instancevariables you own
The 1st bullet says: if you called alloc (or new fooCopy), you need to call release on that object.
The 2nd bullet says: if you use a convenience constructor and you need the object to hang around (as with an image to be drawn later), you need to retain (and then later release) it.
The 3rd should be self-explanatory.
Lots of good information on cocoadev too:
MemoryManagement
RulesOfThumb
As several people mentioned already, Apple's Intro to Memory Management is by far the best place to start.
One useful link I haven't seen mentioned yet is Practical Memory Management. You'll find it in the middle of Apple's docs if you read through them, but it's worth direct linking. It's a brilliant executive summary of the memory management rules with examples and common mistakes (basically what other answers here are trying to explain, but not as well).

ARC reference counting dealloc, and release

I am getting a bit confused. I am creating an app with storyboard, and running it on iPad 1. the application uses a lot of memory, so reached the 120mb, crashes. accordingly to what I have understood to remove this problem you need to release, dealloc... the point is that with ARC this should be automatic. In fact if I add for e.g.: [label1 release]; it gives me an error. But this ARC automatic release and dealloc does not seem to work! Is this because there are different ways to release with ARC??
You don't need to manually retain/release/autorelease with ARC. However if you have active references to a lot of unused objects they will still remain in memory. Profile your app with Instruments and it will show you how many objects you're creating of each class and how much memory they're consuming.
With ARC you still need to think about memory usage you just don't need to worry as much about memory leaks.
NSObject *bigMemObj = [[BigMemClass alloc] init];
//This creates the object in memory. In both arc and manual counting the retain count is 1
//Do stuff
//Prior to ARC you would have had to call [bigMemObj release]; before setting the variable to nil
bigMemObj = nil
//With ARC you don't have to do anything. The compiler inserts the release at compile time
Also read the documentation on declaring iVars __strong vs __weak.
Without looking at your code it's hard to identify what is consuming all the memory but hopefully that should help you determine where to start looking.
You should implement #autoreleasePool{} inside each method. In essence, each method will look like the following:
-(void)methodName{
#autoreleasePool{
//do method stuff
}
}
This will ensure that, upon exiting the autoreleasePool, memory is properly released.
I can't vote this back up, otherwise I would. I think Alessandro is asking about ARC vs using release and dealloc, not about what he's loading!
So, Alessandro, your understanding is correct that with ARC you don't release or dealloc. Therefore, those won't work if you're using ARC. Also, there is no alternative to release/dealloc, since ARC doesn't use it.
My suggestion would be to look at what you're using in the app that is taking up all this memory. Do you have a large number of pictures, for example, that are very large? Keep any graphics as small as possible, matching the resolution of the iPad. Especially the iPad 1, which doesn't have the "retina display".
You can use Autorelease pools in ARC. Here is some documentation on when to use them:
NSAutoreleasePool Class Reference
Advanced Memory Management Programming Guide: About Memory Management

Updating CoreFoundation PriorityQueue implementation to take advantage of ARC for iOS

I found an implementation of a priority queue that primarily uses CFBinaryHeap to work.
I'm currently using the -fno-objc-arc compiler flag to skip the usage of ARC while compiling these files. I attempted to update this code to take advantage of ARC, though I've run into a few snags of understanding.
Is there anyone here who has updated code similar to this for use with ARC?
How do you handle things like free(), and CFRelease()? Can we just get rid of them?
What do you do with the retain and release methods you create for CFBinaryHeapCallBacks?
Do you use __bride or __bridge_transfer to reference the const void * into Objective-C objects? Likewise should you use (__bridge_retained void *) or obj_unretainedPointer() to do the reverse?
ARC basically is a compiler technology that automatically inserts calls to -retain, -release, and -autorelease as needed. It does not remove the need for retains and releases, it just makes them automatic (in the process, optimizing out many that are not required, and playing other tricks to make various common patterns much more efficient than if you did it by hand).
ARC knows nothing about Core Foundation, nor about void* objects, malloc, free, or anything other than ObjC memory management.
This means that as long as you use Core Foundation objects, you should continue to use CFRelease. And if you malloc memory, you should continue to free it.
But.... what if you want to take memory that was created by Core Foundation and transfer it to Cocoa via a toll-free bridge? That's where __bridge* comes in. One of the best sources of information is the clang docs themselves. A great blog article is Everything you need to know about ARC. It includes many useful links to the definitive information.
But here's the short answer (from Transitioning to ARC)
NSString *c = (__bridge_transfer NSString*)my_cfref; // -1 on the CFRef
CFStringRef d = (__bridge_retained CFStringRef)my_id; // returned CFRef is +1
Using __bridge_transfer logically moves a CF object into Cocoa. Using __bridge_retained logically moves a Cocoa object into CF. You use these when you are really transferring ownership of the object. In the above example, you generally shouldn't continue using the my_ variables in my opinion. These are particularly useful in cases where you are returning the result out of the function. These should be used for their logical ownership functionality only. Don't use them as a way to "fake" a manual call to retain or release.
If you just want to have a temporary "bridged" pointer to the object so you can use it in CF or Cocoa without transferring it, then use __bridge. That's a no-op that says "don't do any memory management, just let me pretend for the moment that it's the other kind of object." If you do a lot of toll-free bridging, you'll wind up using __bridge quite a lot (making it seem like a small toll.... :D)
Here is a pure objective-c implementation of PriorityQueue, that supports ARC:
https://github.com/jessedc/JCPriorityQueue/tree/experimental/heap-queue
Is simple to implement non ARC lib into XCode project. Just open "Build Phases"(menu when click on your project target) -> "Compile Sources" and to files, which are not using ARC add by double click flag "-fno-objc-arc" and your're done. So simple :)

Does ARC work with Core Graphics objects?

I recently started a new project using Automatic Reference Counting (ARC).
When I assigned the contents of a CALayer:
UIView* view = ...
UIImage* image = ...
view.layer.contents = image.CGImage
I got an error
Implicit conversion of a non-Objective-C pointer type 'CGImageRef' to 'id' is disallowed with ARC
Simply casting the CGImageRef to id hides the error, but I was wondering if the ARC still functions correctly then?
You should really check out the ARC videos from WWDC 2011. They are available on the developer site and open through iTunes. Especially:
• Session 323 – Introducing Automatic Reference Counting
• Session 322 – Objective-C Advancements in Depth
Also, the ARC reference notes:
https://developer.apple.com/library/content/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html
Both the reference notes and the videos discuss Core Graphics (et al) and how they work with ARC.
Specifically, look at the section called "Managing Toll-Free Bridging"
In many Cocoa applications, you need to use Core Foundation-style objects, whether from the Core Foundation framework itself (such as
CFArrayRef or CFMutableDictionaryRef) or from frameworks that adopt
Core Foundation conventions such as Core Graphics (you might use types
like CGColorSpaceRef and CGGradientRef).
The compiler does not automatically manage the lifetimes of Core
Foundation objects; you must call CFRetain and CFRelease (or the
corresponding type-specific variants) as dictated by the Core
Foundation memory management rules (see Memory Management Programming
Guide for Core Foundation).
If you cast between Objective-C and Core Foundation-style objects, you
need to tell the compiler about the ownership semantics of the object
using either a cast (defined in objc/runtime.h) or a Core
Foundation-style macro (defined in NSObject.h): [...]
Jörg Jacobsen has a good summary overview of the bridging options as well: Managing Toll-free Bridging in an ARC’ed Environment.
__bridge_retained (n.b.: only use it when casting from object pointer to C type pointer): I (the programmer) need to reference this object
for some time in the dark world of C type pointers which is opaque to
you, ARC. So please, please do not release this object while I still
need it. I (the programmer) promise to release it myself (in the dark
world) when I’m done with it
__bridge_transfer (n.b.: only use it when casting from C type pointer to object pointer): I (the programmer) hand over to you, ARC, an
object that I own and that I am no longer interested in in the dark
world of C type pointers that is opaque to you. Whenever you, ARC, are
done with that object please release it yourself, because you know the
right time and thus save me some work not having to do it myself.
__bridge: ARC, you keep balancing out your retains and releases as I keep balancing out mine in the dark world of C type pointers which
is…. Whenever I need to hold on to an object in the dark world I will
retain it myself and release it when appropriate. I don’t need any
extra contract with you, ARC.
Despite the references pointed out by Steve, I believe the case you show above might be special. From the Transitioning to ARC Release Notes, pay attention to the section "The Compiler Handles CF Objects Returned From Cocoa Methods":
The compiler understands Objective-C methods that return Core
Foundation types follow the historical Cocoa naming conventions (see
Advanced Memory Management Programming Guide). For example, the
compiler knows that, in iOS, the CGColor returned by the CGColor
method of UIColor is not owned.
The code example they provide:
gradientLayer.colors = [NSArray arrayWithObjects:(id)[[UIColor darkGrayColor] CGColor],
(id)[[UIColor lightGrayColor] CGColor], nil];
relies on the known return of CGColors from these methods (they are missing the cast to id that I've added in the above code, which should be corrected in their documentation soon).
Because [image CGImage] follows the naming conventions, I believe the CGImage will be bridged properly here. I think that your cast to id should be all that you need here.
One popular answer to layer.contents = (id)image.CGImage question is layer.contents = obj_unretainedObject(image.CGImage).
I do =(__bridge id)image.CGImage.

Releasing Core Foundation object references

Do I need to release a Core Foundation objects to clear up memory? And if so, how?
For example, in the code:
ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef peopleArray = ABAddressBookCopyArrayOfAllPeople(addressBook);
do I need to release peopleArray? What about addressBook?
Yes, in CoreFoundation you have to release anything with Create or Copy in the name. You do this with CFRelease(). In your case, you should be releasing both the array and the address book references.
The rules for memory management in Core Foundation are similar to those in Cocoa: if the method that returns a reference contains the words "create" or "copy", you own the reference and must call CFRelease() on that reference to relinquish ownership. Otherwise, you do not own the reference and must call CFRetain to take ownership (necessarily requiring a subsequent CFRelease to relinquish that new ownership). These rules, as taken from the Memory Management Programming Guide for Core Foundation are:
If you create an object (either
directly or by making a copy of
another object—see “The Create
Rule”), you own it.
If you get an
object from somewhere else, you do
not own it. If you want to prevent it
being disposed of, you must add
yourself as an owner (using
CFRetain).
If you are an owner of an
object, you must relinquish ownership
when you have finished using it
(using CFRelease).
In your example, both the addressBook and the peopleArray must be released. Since there is no autorelease equivalent in Core Foundation, if you are returning the a reference from a method, return the array without releasing it. You should (unless you're being evil) then include "create" in the method name to indicate to the caller that they now own a reference to the returned object. In this case, CFArray is toll-free bridged to NSCFArray, an Objective-C object that inherits from NSObject. You can thus cast peopleArray to an NSArray* and autorelease that, if you need to return it from a function/method:
return [(NSArray*)peopleArray autorelease];
Note that this only works for toll-free bridged classes. My understanding is that it's rather difficult to make your own toll-free bridged classes and only the primitive (string, array, etc.) CF classes are toll-free bridged, so this approach won't work always. Finally, if you can avoid using autorelease (i.e. you can make your memory management more explicit), that's probably always a good thing.
Another small point that no-one has mentioned yet, some CF classes have a "toll-free bridge" with their NS counterpart. CFString and NSString, CFArray and NSArray are both examples. This is relevant as you can just use release with these classes.
See this other StackOverflow question for more information.
I would suggest reading Apple's guide on Core Foundation memory management for an in-depth discussion of this. They have a similar guide for general Cocoa memory management as well.
To release a CF object, you would call the CFRelease function.
For ARC you can use.
return (__bridge_transfer NSArray*)peopleArray;
"__bridge_transfer" will transfer the ownership to ARC and therefore you don't need any further release call.