6 ms·
How Memory Management Works on iOS
- kelnos 15y ago3. 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.
- andrewljohnson 15y agoYou are right, I will correct it. Also, hopefully this post is useful as is at least for beginners, though adding information on autorelease pools would be good for sure.
- rbritton 15y agoOn the topic of properties, I also find it helpful to define the property and variable to have different names (e.g., NSString _foo; for the variable and @property (nonatomic, copy) NSString foo; for the property). When mapped through @synthesize foo = _foo;, it avoids confusion about the memory management necessary for a particular value.
- zpasternack 15y agoThe 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 15y agoSimilar, but not the same, though yes, releasing it can be done in the same manner.
- macrael 15y agoApple's Memory Management Programming Guide: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html http://developer.apple.com/library/mac/#documentation/Cocoa/...
- tylerc230 15y agoThis: - (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 15y agoIn 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?
- azsromej 15y agothat works fine too and prevents any issues with releasing the variable before it gets retained again. objects might hang around in memory a little longer this way, though (for foos != bars)
- tylerc230 15y agoThat would also work, autorelease is generally considered slow though.
- pshc 15y agoThe cleanest version IMO is - (void) setFoo:(NSString*)bar { [bar retain]; [foo release]; foo = bar; } which harmlessly increments and decrements for self-assignment.
- andrewljohnson 15y agoAh, trickier than I thought. I posted an EDIT to the blog post.
- zpasternack 15y ago> 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."
- zpasternack 15y ago> “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.
- puls 15y agoGood 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 15y agoI 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
- jazzychad 15y agoit 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 15y agoA 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 '_'
- stevejohnson 15y agoThis 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].