

How Memory Management Works on iOS - dsil
http://www.gaiagps.com/news/article/(Technical%20Post)%20How%20Memory%20Works%20on%20iOS

======
kelnos
_3\. When you type self.foo = bar, there is an implied retain. If you set a
class variable without the "self," there is no implied retain._

No no no no no... That is absolutely incorrect. Only properties declared
"retain" do that.

    
    
      @property (nonatomic, assign) NSObject *foo;  // doesn't retain
      @property (nonatomic, copy) NSObject *bar;  // doesn't retain
      @property (nonatomic, retain) NSObject *baz;  // *does* retain
    

(The 'nonatomic' isn't related to the retain/no-retain semantics, but most
properties are declared nonatomic, as atomic properties have some locking
overhead.)

On a side note, a discussion of iOS/Mac memory management isn't very useful if
it doesn't talk about how autorelease pools work.

~~~
zpasternack
The same thing applies to "copy" properties. If you do "self.foo = bar;" when
foo is a copy property, you have taken ownership of that object, and need to
release it later (hopefully by doing "self.foo = nil;".

~~~
kelnos
Similar, but not the same, though yes, releasing it can be done in the same
manner.

------
macrael
Apple's Memory Management Programming Guide:
[http://developer.apple.com/library/mac/#documentation/Cocoa/...](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html)

------
tylerc230
This:

    
    
      - (void) setFoo:(NSString*) bar {
        [foo release]; 
        foo = [bar retain]; 
      }
    

should be:

    
    
      - (void) setFoo:(NSString*) bar {
        if(bar == foo)
           return;
        [foo release]; 
        foo = [bar retain]; 
      }
    

so that you can do without crashing:

    
    
      obj.foo = obj.foo;

~~~
hrktb
In the same line of thinking, for object that don't hold memory space I need
to mark on the spot, I use :

    
    
      - (void) setFoo:(NSString*) bar {
        [foo autorelease]; 
        foo = [bar retain]; 
      }
    

which I expect to do nothing (retain count is unchanged) when foo == bar. I do
it for concision, am I missing something?

~~~
pshc
The cleanest version IMO is

    
    
      - (void) setFoo:(NSString*)bar {
        [bar retain];
        [foo release]; 
        foo = bar;
      }
    

which harmlessly increments and decrements for self-assignment.

------
zpasternack
> 2\. When you type "alloc" there is an implied retain.

It's not quite that simple. The official rule from Apple's Memory Management
Programming Guide most succinctly states "You take ownership of an object if
you create it using a method whose name begins with “alloc”, “new”, “copy”, or
“mutableCopy” (for example, alloc, newObject, or mutableCopy), or if you send
it a retain message."

------
stevejohnson
This article gives bad advice. If you use his examples your program will
crash; see tylerc230's comment. Also, it does not follow generally accepted
style practices, such as the lack of a space after a closing bracket
[[like]this].

------
zpasternack
> “Typing self.foo releases and nils the variables.” Yes, if it’s a retain or
> copy property.

> “Just typing foo = nil is a memory leak.” Yes, if you had retained the
> object, but not if it were a weak reference. Admittedly, this is a semi-rare
> scenario.

------
jazzychad
it also help when you understand how the dot-notation works in objective-c...
it's not like other languages where you are just accessing a member of an
object.

    
    
        foo = object.bar;
        is syntactic sugar for
        foo = [object bar]; //where 'bar' is a method call
    

and

    
    
        object.foo = bar;
        is syntactic sugar for:
        [object setFoo:bar];
    

I dealt with a lot of goofy memory errors trying to figure out why using
'self.foo' and just 'foo' inside of a class acted differently. Now it makes
much more sense.

~~~
nomurrcy
A lot of developers (myself included) don't use the dot syntax for property
access for this reason and another:

x.foo = z; becomes an ambiguous statement in obj-c when you use dot access. Is
x an object? then this is a message send. Is x a struct? then this is an
assignment.

Typically in my interface file, I explicitly define my member variables with a
leading '_';

@interface Foo { NSObject __bar; }

@property(nonatomic, retain) NSObject _bar;

@implementation Foo @synthesize bar=_bar; @end

And if I want to access bar I use [x bar], [x setBar:y]; it is easy to
visually scan for direct use of member values by looking for the leading '_'

------
puls
Good article, though it kinda violates rule #1 of Cocoa memory management:
don't try to summarize the rules, because you'll probably miss a subtlety.
Link to the Apple docs instead.

~~~
mdonahoe
I lived in doubt of my code until I decided to fully understand memory
management. Now that I understand it, it seems simple enough to summarize...
but thats the trick

