I’m working on learning Objective-C, and I’m trying to get a feel for the memory management. I’m fairly familiar with C memory management, but I’m trying to figure out how different ObjC is.
Let’s say I have a class called Complex that is used for holding complex numbers, which has a method -(Complex*)add:(Complex*)c; that adds the passed in complex number to self (Complex is a mutable object, let’s say).
So I can call it this way:
Complex *c = [[Complex alloc] withReal: -3.0 andImag: -2.4]; // c = -3.0-2.4i
[c add : [[Complex alloc] withReal: 1.0 andImag: 2.0]]; // now c = -2.0-0.4i
What happens to the memory used for the temporary object created in the call to add? I assume it’s a memory leak; is this the correct code?
Complex *c = [[Complex alloc] withReal: -3.0 andImag: -2.4]; // c = -3.0-2.4i
Complex *b = [[Complex alloc] withReal: 1.0 andImag: 2.0]; // b = 1+2i
[c add : b]; // now c = -2.0-0.4i
[b release];
Bonus noob question: would the Objective-C 2.0 GC deal with the situation?
First, with my “best practices” hat on, when you create custom classes, the Objective-C idiom is to name the initializers (equivalent of “constructors” in other languages) with a leading “init”. Also, try not to abbreviate parts of the method selector, or the named parameters.
For example, instead of this:
You should consider doing this:
The “and” before the second part is a matter of taste — it’s perfectly acceptable to use it, but I prefer it without, since you probably wouldn’t use it for methods with 3+ parameters. For example, it would more verbose than necessary if you were creating an RGB color to use
-initWithRed:andGreen:andBlue:— writing/using-initWithRed:green:blue:is usually preferable.For your actual question, I completely agree that creating a convenience class constructor is the smart way to go for situations such as these. It’s visually much cleaner than alloc-init-autorelease each time you need a throwaway instance. Matching the changes above, I would tweak @kent’s answer to look like this:
For the bonus question, yes, Objective-C 2.0’s GC would handle this just fine; most well-written retain-release code works as-is under GC, especially if you are careful to set pointers to nil when you no longer need them. When GC is enabled, calls to retain/release/autorelease are essentially no-ops, and objects are collected once there are no references to them. Once the last pointer to an object is lost, or goes out of local scope, the object is eligible for collection. (Technically, the GC only counts strong references, but unless you’re knowingly using weak references, the distinction is probably irrelevant for now.) Just remember that garbage collection is currently NOT supported on iPhone.