Where to release a copy to the setter?

In my setter, I have an input string that I copy to avoid any problems if the original is changed.

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [newName copy];
    }
}

      

My question is, how do I make a copy, where should I release it, or am I just doing auto advertisements? i.e.

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [[newName copy] autorelease];
    }
}

      

Gary

+2


source to share


4 answers


In my setter, I have an input string that I copy to avoid any problems if the original is changed.

- (void)setName:(NSString *)newName{
  if(name != newName) {
      [name release];
      name = [newName copy];
  }
}

      

My question is, how do I make a copy, where should I release it, or am I just doing auto advertisements? i.e.

- (void)setName:(NSString *)newName{
  if(name != newName) {
      [name release];
      name = [[newName copy] autorelease];
  }
}

      

As I said to your other question , it autorelease

translates to "send release

later". This means it counts as a release.

So your second example outputs the old value name

(good), then creates a copy of the new (good), then puts the new on the line to be released (bad), and then puts that now -doomed into an instance variable (very bad).



The first example is correct because you are still keeping the hold on the object after you put it into an instance variable.

As I said on your other question, I think you should consider memory management rules .

+4


source


When you do copy

, the object will be saved. Is this what you want. If you automatically register it, it will eventually be released. So your first example is correct. The second will crash your application.



If you are worried about what happens when the object is freed, remember that you need release

any references in your method dealloc

.

+6


source


Your first example is correct:

- (void)setName:(NSString *)newName{
    if(name != newName) {
        [name release];
        name = [newName copy];
    }
}

      

but as you suspect copy

should be balanced with release

. Assuming it name

has the usual semantics (i.e. you want it to stay until the containing class instance is freed), balancing release

should appear in dealloc

(unless you are using garbage collection):

- (void)dealloc {
    [name release];
    //release other instance variables of type id

    [super dealloc];
}

      

Re-read the memory Cocoa Control Programming Guide if you're still confused.

+1


source


Your first example is correct. So, Peter Hosei - you better get familiar with the rules of memory management.

If that helps, my preferred approach, as it looks a little cleaner:

- (void)setName:(NSString *)name
{
  name = [name copy];
  [_name release];
  _name = name;
}

      

+1


source







All Articles