Why not? The -init calls -init designed to return a given object while storing the number +1, and performing a “temporary save” is the safest way to ensure that the “I” remains alive throughout this initialization method. Think about what happens if we clear the Objective-C abstraction layer and turn -init into a function pointer that IMP allows:
id init(id self, SEL _cmd) { //+0 self given requires explicit retain to guarantee lifetime //... //(if retained) +1 self is returned; (if not retained) +0 self is deallocated }
If you set a self with a save count of +0 (as is usually the case with most methods that save their arguments, i.e. setters), then you will need to ensure that somewhere in the inheritance chain someone was good enough, to keep yourself away from what happened, to highlight it (ending in self , having a rather ambiguous value of saving +1). But, if you get an “I” with a save factor of +1, and you yourself save it, you can be sure that it remains alive using your -init method and that you and only you own self . And if the given "I" was not "alive", then you are guaranteed to return zero, and not an object in the middle of liberation. So the above becomes (in pseudo-C):
id init(__attribute((ns_consumed))id self, SEL _cmd) { //implicit retain of +1 self returns self with +2 //... //implicit release of +2 self returns self with +1 }
I like to call this template “old-school atomic access”, and it was used on Apple infrastructures developed before the @synchronized {} atomic getters were created. When you use a getter supported by public iVar. You will often see methods that follow this pattern, written as follows:
- (NSView *)view { //explicit retain-autorelease of +1 variable is +2 -> +1, guaranteed access or nil. return [[_view retain]autorelease]; }
But all this does not affect ownership rules with the exception of -init and family. -init methods return +1 objects, but who exactly owns them? Well, the allocator * still has a hand in the reference to the variable, and self = [super init] actually saves nothing (and it also has to obey the "returns +1" rule). Well, again I have to go to the pseudo-code, but this time it will be in Objective-C:
- (id)init { //self is +1 because -init must return +1 self = [super init]; //implicit [self retain]; leaves self with a +2 reference count //... //implicit [self autorelease]; leaves self with a +1 reference count return self; }
OK, so now you have a +1 object floating around declared by the distributor, since you "declare" it? Appointment of course! The point of implicitly __strong locals and __strong properties is to restore an object from a distribution object.
- (void)f { //Freestanding +1 variable is not owned by the caller, will be deallocated when the method //passes out of scope. [[NSObject alloc]init]; //Implicitly __strong local captures reference away from allocator entity, //which "autoreleases" it ownership //We now "own" the returned object. NSObject *obj = [[NSObject alloc]init]; //Strong property captures reference away from local, saves the object from being deallocated //when the method passes out of scope self.object = obj; }
* The allocator, in the context of this answer, refers to functions that ultimately call malloc() to allocate space for the object.