3

Possible Duplicate:
Properties and Instance Variables in Objective-C 2.0

I'm using properties only for ivars that don't require any real validation when getting or setting a value for a class that I'm authoring.

Ex: 
@interface ClassB : NSObject
{
    // No ivars
}

@property (nonatomic, retain) ClassA *obj;
@property (nonatomic, retain) NSString *str;

Whenever I call these methods within the class I'm always using self.obj/self.str or [self obj]/[self str]. This way in order to set the state of the object you are forced to go through the property so that the references are more carefully managed by the compiler produced getters and setters. With that said, are there any problems that I can run into creating my classes this way? Also, with no ivar present, is any "release" needed in an overwritten "dealloc" method in the @implementation file?

Community
  • 1
  • 1
5StringRyan
  • 3,604
  • 5
  • 46
  • 69

3 Answers3

3

If you're using the @synthesize directive to create the property accessors, the compiler will also create any ivars that you leave out of the class declaration. You do still need to release your ivars. It used to be that you couldn't access synthesized ivars directly and so had to use the property setter in your -dealloc method like this:

- (void)dealloc
{
    self.obj = nil;
    self.str = nil;
    [super dealloc];
}

These days, though, the compiler will let you access the synthesized ivar directly, so you can release it instead of calling the setter (which is a good idea in -dealloc, and a bad idea everywhere else):

- (void)dealloc
{
    [obj release];
    [str release];
    [super dealloc];
}

This will change when you eventually convert your code for ARC (automatic reference counting) because the compiler will take care of releasing your ivars in -dealloc for you. Most of the time, this means that your -dealloc implementation can just go away.

BJ Homer
  • 48,806
  • 11
  • 116
  • 129
Caleb
  • 124,013
  • 19
  • 183
  • 272
  • Would it be better programming practice (Well, until ARC code) to do a pointer assignment to nil, or do a release? – 5StringRyan Aug 22 '11 at 22:49
  • If you retained an object, you have to release it. Just setting the pointer to nil creates a leak -- you lose the reference to the object, but you never release the object. If you want to set the pointer to nil *after* releasing it, feel free. Some people like to see the pointer change to nil. It doesn't help very much in -dealloc, though, because `self` is about to be deallocated anyway. – Caleb Aug 22 '11 at 23:06
  • In BJ Homers example, since he is directly assigning self.obj/self.str = nil, since they aren't released and the pointers are assigned to nil, are leaks created? – 5StringRyan Aug 22 '11 at 23:15
  • 2
    If he's doing self.obj = nil, the setter is being used which always releases the previous content of the variable (if declared "retain"), so no leaks. – Flyingdiver Aug 22 '11 at 23:25
  • ahh your right because the setter will release the previous object that obj is pointing too, and will point the obj to the new memory location with the assignment (this case nil) and then retain that for ownership (which does nothing in this case, since messages can be sent to nil without exceptions). – 5StringRyan Aug 22 '11 at 23:37
2

It's not necessary to have your IVars declared explicitly. I'd even recommend omitting them because you should ALWAYS access IVars via accessors (as you pointed out what you already do.)

You will not run in any problems, except that the debugger doesn't catch the IVars directly anymore (they won't display nicely next to your console.) - But that's not really an issue.

In your dealloc method you will not need to release them anymore. What you will need to do is nil them.

self.obj = nil;

--

Here's a brief overview of what the property attributes actually mean: (That's to show you that a release happens when you nil a variable in the dealloc)

assign

@property (assign) NSString *name;

name = newValue;

retain

@property (retain) NSString *name;

if (name != newValue) {
   [name release];
   name = [newValue retain];
}

copy

@property (copy) NSString *name;

if (name != newValue) {
   [name release];
   name = [newValue copy];
}
pkluz
  • 4,871
  • 4
  • 26
  • 40
  • 1
    This is not true you should not `always` go through getters and setters it is in fact encouraged to access the ivars directly in `init` and `dealloc` methods to avoid side potential side effects. Also you can still access a synthesised property to release it e.g. `[_myProperty release]` meaning you can avoid the indirect access like in the `dealloc` as previously mentioned – Paul.s Aug 22 '11 at 22:13
  • Good point. There you got an exception to the aforementioned rule of thumb :-) – pkluz Aug 22 '11 at 22:21
  • @Paul.s: The synthesized ivar does not have a leading underscore; it has exactly the same name as the property. – jscs Aug 27 '11 at 07:11
  • Yup sorry I didn't really have space to mention it's common to prefix ivars with something so you know when you are directy accessing them. I should have left of the prefix in this example – Paul.s Aug 27 '11 at 07:19
  • From The Objective-C programming language: Declared Properties | Using Properties | dealloc: "If you are using the modern runtime and synthesizing the instance variable, however, you cannot access the instance variable directly, so you must invoke the accessor method: - (void)dealloc { [self setProperty:nil]; [super dealloc]; }" http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/objectivec/Chapters/ocProperties.html#//apple_ref/doc/uid/TP30001163-CH17-SW16 – Johan Pelgrim Sep 30 '11 at 06:57
  • @Johan: That was briefly true, but the restriction has been lifted (this note no longer appears in the docs). The ivar is perfectly well accessible from the synthesizing class, though it is inaccessible from others, including subclasses. – jscs Jan 10 '12 at 19:24
0

The compiler is automagically creating the ivar for you, even though it's not explicitly defined in the ivar list. It's got the same name as in the property list. The compiler now just doesn't require the duplicate definition line.

If you have properties (ivars) that need to be released, do it.

Flyingdiver
  • 2,142
  • 13
  • 18