Well, there are already three answers that cover the main things so I'll focus on a single detail here, that isn't already mentioned:
3.) I couldn't find the Leaks tool in Xcode 4.2. Where did it go? Or don't we have to check for leaks anymore?
Yes we do still need to check for leaks:
ARC is not garbage collection, it is automated retain/release.
Thus, it is still possible — in fact, it's pretty easy — to create leaks!
Consider the following example:
@class Puppet;
@protocol PuppetDelegate : <NSObject>
- (void)puppetDidTwistStrings:(Puppet *)puppet;
@end
@interface Puppet : NSObject {
id <PuppetDelegate> delegate_;
}
- (id)initWithPuppetDelegate:(id <PuppetDelegate>)delegate;
- (void)unravelStrings;
@end
@implementation Puppet
- (id)initWithPuppetDelegate:delegate
{
if (!(self = [super init])) return nil;
delegate_ = delegate;
return self;
}
// assume some implementation for unravel strings
@end
@interface MasterOfPuppets : NSObject <PuppetDelegate> {
NSMutableArray *puppets_;
}
- (void)puppetDidTwistStrings:(Puppet *)puppet;
- (void)bringOutAPuppet;
@end
@implementation
- (id)init
{
if (!(self = [super init])) return nil;
puppets_ = [[NSMutableArray alloc] init];
return self;
}
- (void)bringOutAPuppet
{
Puppet *newPuppet = [[Puppet alloc] initWithPuppetDelegate:self];
[puppets_ addObject:newPuppet];
}
- (void)puppetDidTwistStrings:(Puppet *)puppet
{
BOOL isOurPuppet = [puppets_ containsObject:puppet];
if (!isOurPuppet) return;
[puppet unravelStrings];
}
@end
This example is (admittedly) a little stupid, but this code will leak, and ARC is not going to help you about it, whereas garbage collection would:
- A MasterOfPuppets can have many puppets, which he stores in an instance variable — so far so good.
- A Puppet has a delegate which it is going to inform if its strings are entangled — and here it starts.
Whereas in non-ARC code an instance variable was simply a pointer that was being assigned to, ARC assumes that if you stash something in a variable, you want to cling on to it and it will retain
the value unless you tell it not to.
So you have a classical retain-cycle here and ARC won't save you from those.
This may seem a contrived and far-fetched example, but it's not: I've seen this quite a bit in delegate relationships.
(The solution, by the way, is pretty simple: declare Puppet
's delegate_
instance variable as weak
and everything works as it should.)