Изменения в новых версиях / Objective-C 2011: ARC

// *** before: ***
// the rule was memorised by hand: alloc, new, copy and retain give you an
// object you own, and you owe it exactly one release
@implementation Library
- (void)load {
    Book *book = [[Book alloc] initWithTitle:@"Moby-Dick"];
    [self.books addObject:book];
    [book release];                 // owned by alloc - released here

    Book *found = [self.books objectAtIndex:0];
    [found retain];                 // not owned - retained to keep it
    self.current = found;
    [found release];
}

- (Book *)makeBook {
    Book *book = [[Book allocinit];
    return [book autorelease];      // the caller does not own the result
}

- (void)dealloc {
    [_books release];
    [_current release];
    [super dealloc];                // and the last line was always this
}
@end

// *** in version 2011: ***
// the compiler inserts retain, release and autorelease itself, at the same
// places a careful person would have put them
@implementation Library
- (void)load {
    Book *book = [[Book alloc] initWithTitle:@"Moby-Dick"];
    [self.books addObject:book];    // no release: the variable owns it
                                    // until the end of the block

    Book *found = self.books[0];
    self.current = found;           // the setter holds it by itself
}

- (Book *)makeBook {
    return [[Book allocinit];     // no autorelease either
}

// dealloc may be left out entirely; if it is written, it releases nothing
// and [super dealloc] is now forbidden
@end

// ⚠️ retain, release, autorelease and [super dealloc] became compile errors
// under ARC. ARC is not a garbage collector: it is the same counting, only
// written by the compiler, so a retain cycle still leaks