4

In my UIViewController subclass, I have 3 UIView's with each a @property as an IBOutlet. I do not use these properties at all in my code. The views get instantiated as soon as the view controller is created and they are deallocated when the view controller is deallocated.

I was thinking; can't I just remove the @property's? I did, and I could still connect my instance variables (with IBOutlet) in Interface Builder.

So my question now is; is there any use for properties in combination with Interface Builder, or is it OK to leave them out? Is it required for some memory management or something? Or are they really just for use in your own code?

And if I do leave them out, do I still need to release them in dealloc?

Rits
  • 5,105
  • 4
  • 42
  • 53

5 Answers5

10

They're not necessary, but they're strongly encouraged for the simple fact that they clarify memory management.

For example, if you declare an outlet via the ivar, then what is its retain policy? Is it retained? Is it autoreleased? Are you the owner? Does someone else also own it? There is a lot of ambiguity there (especially with those accursed top level objects, which behave differently on the Mac than on the iPhone).

On the other hand, if you declare the outlet via a property, there is no ambiguity, because the memory management policy is directly stated in the declaration. In addition with the presence of the property, the nib unarchiving will see the setter and use that, thereby ensuring that nothing strange is going on with transferring object ownership, etc.

In a nutshell, you can declare outlets without using @property (which we all had to do before they were introduced in 10.5), but there's no good reason to not use them. They really make the code a lot clearer as to what exactly is going on.

For more info on the absurdity of nib object memory management, check out this page in the documentation.

Dave DeLong
  • 242,470
  • 58
  • 448
  • 498
  • for interest if not defining a @property it should use the default values, so the variables would all get assign instead of retain, readwrite and atomic ;) –  Jan 02 '11 at 18:34
  • @iPortable not necessarily. Top level objects have some extra funky caveats. Sometimes you still need to release them, sometimes you don't. Like I said, it's crazy stupid, and using a property just makes everyone's job easier. – Dave DeLong Jan 02 '11 at 18:45
  • I hate the thought that someone can access my variables from another class. Is there a way to deny that especially? –  Jan 02 '11 at 18:48
  • I decided to remove them where possible. It's less code for me. I know it's only 2 lines of code per @property, but if I have 3 @property's, that makes 6 lines of code. – Rits Jan 03 '11 at 00:50
  • This post is very old. Now a days ARC is taking care of memory. Beside this calling getter and setter is more expensive. – Bernard Jun 07 '16 at 12:16
2

yes you can:

@interface SomeClass : UIViewController {
    IBOutlet UILabel *myLabel;
}

@end

@property is only for defining memory management and getter and setter, read-write ability etc.

  • 2
    And if I do leave them out, do I still need to release them in dealloc? – Rits Jan 02 '11 at 18:11
  • I don't know exactly (maybe have to read the documentation again) but I release all object that I declared in my header file. (maybe it's wrong but I get no error at all ^^) –  Jan 02 '11 at 18:14
  • @Rits You don't have to release them in dealloc as they are not retain when assigned to ivars. Only if you use propert (retain) you need to release in dealloc – Piotr Czapla Jan 02 '11 at 18:23
  • 1
    @Rits your comment is the exact reason why it's recommended to declare outlets via properties. – Dave DeLong Jan 02 '11 at 18:24
  • @Piotr that's not always true. – Dave DeLong Jan 02 '11 at 18:24
  • @Dave Do you think about the cases when you explicitly retain your ivars or about some other cases? – Piotr Czapla Jan 02 '11 at 18:37
2

There are two reasons to use property for views:

  • Easier/safer memory managment (Really good reason)
  • Exposing your interface to other clasess (usually bad coding practice)

I always use properties just to make sure that my code doesn't crash if I forget to nil the IBOutlets in viewDidUnload. After all it isn't that hard to just write 2 lines of code.

If you would like to save some typing don't declare ivars at all. The code below works just fine:

@interface MyController : UIController {
}
@property (nonatomic, retain) IBOutlet UIImageView* myImage;
@end

@implementation MyController
@synthesize myImage;

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

- (void) viewDidUnload()
{ 
   self.myImage = nil;
   [super viewDidUnload];
}
@end
Piotr Czapla
  • 25,734
  • 24
  • 99
  • 122
  • in all apple's sample codes a IB var gets nil in viewDidUnload and is released in dealloc –  Jan 02 '11 at 18:36
  • @iPortable It is true however it doesn't hurt to nil it in dealloc and it won't crash if you change your @property from 'retain' to 'assign'. – Piotr Czapla Jan 02 '11 at 18:41
  • @iPortable I've posted a question regarding nilling the properties: http://stackoverflow.com/questions/4579891/objective-c-style-question-do-release-or-nil-properties-in-dealloc – Piotr Czapla Jan 02 '11 at 18:51
1

If you're not planning on manipulating or accessing information about your views from other view controllers or objects and planning on using them internally (in owning view controller) you don't need @property statments at all. Just define them as IBOutlet instance variables in your view controller's interface.

Eimantas
  • 48,927
  • 17
  • 132
  • 168
0

Interface Builder or the NIB loader doesn’t depend on the properties to be there. If the connected variables can be accessed via KVC the nib loader can make the connections.

But you really should consider using synthesized properties instead of hand-written accessors. This is much less error-prone because it doesn’t require as much boilerplate code. The less code you have to write the better.

Sven
  • 22,475
  • 4
  • 52
  • 71
  • Maybe only I can't see the dependency so just want to make sure: there is no need for synthesizing the values because if no @property is defined it will use the default getter and setter. –  Jan 02 '11 at 18:18
  • Yes. And even if you have the `@synthesize` line in there your hand-written setter and getter will be used. `@property NSString *foo` in the header is just a different way for writing `-(NSString *)foo; -(void)setFoo:(NSString *)newFoo;` and recording some information that `@synthesize` uses. – Sven Jan 02 '11 at 18:21