tags:

views:

134

answers:

3

Given the following code snippet from inside a method;

NSBezierPath * tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
      [tempPath retain];
      [path release];
   [self setPath:tempPath];

Am I responsible for releasing tempPath or will it be done for me?
The setPath is @synthesized so I probably would be able to leave out the [path release] as well?

I know the better way of doing this is simply;

[path appendBezierPathWithOvalInRect:pathRect];

But, being new to Objective C and Cocoa, I'm trying to understand how things stick together.

---ADDED CONTENT

Leaving out the [tempPath retain] results in a crash in the NSView object that uses the paths.
The result from the debugger:

(gdb) po [0x145dc0 path]

Program received signal EXC_BAD_ACCESS, Could not access

memory. Reason: KERN_PROTECTION_FAILURE at address: 0x00000021 0x93c56688 in objc_msgSend ()



CONFESSION OF GUILT - my mistake. Hope someone else will get something useful from my mistake. I had used assign in place of retain in the @property declaration. Fixing those made the code work as expected.

THANKS FOR THE HELP GUYS

+1  A: 

You don't need to release tempPath.

You can also drop the [tempPath retain] and the [path release]. These are taken care of by synthesizing the set method.

Max Stewart
+3  A: 

If path is the instance variable backing the -setPath: method then no, you absolutely should not be releasing it outside of your -dealloc method. You don't need to manually retain your tempPath object since you're using an accessor to save that object. Your accessors, -setPath: in this case, -init and -dealloc methods should be the only methods where you'd be calling -retain and -release on your instance variables.

Your code works just as well like this, and with less chance of a memory leak:

NSBezierPath *tempPath = [NSBezierPath bezierPathWithOvalInRect:pathRect];
[self setPath:tempPath];

Since the -bezierPathWithOvalInRect: method returns an autoreleased object and your accessor will retain it you don't need to do anything else with it.

Ashley Clark
Thanks Ashley. If I leave out the retain, the program crashes later on in an NSView object that uses the paths.
Joe
+1  A: 

Let's look at this another way:

If you weren't using synthesized accessors, you'd be writing them yourself. In their simplest forms they would look like this:

- (NSBezierPath *) path {
    return path;
}

- (void)setPath:(NSBezierPath *)newPath {
    if (path == newPath) {
        // both objects have the same pointer so are the same.
        return;
    }

    [path release];
    path = [newPath retain];
}

You can see that the old path is released and the new path is retained within the setter, so you do not need to do this from within your method which can be written as

self.path = [NSBezierPath bezierPathWithOvalInRect:pathRect];
Abizern