Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objective-c modern runtime using both properties and ivars in interface block

I've seen code examples (from the book Beginning iPhone 4 Development) where they both declare ivars inside the interface block and then declare properties for the same. Like this:

@interface ViewController : UIViewController {
    UITableView *table;
}

@property (nonatomic, retain) IBOutlet UITableView *table;

What would be the purpose/benefit of this? As I understand that with the modern runtime version (iPhone and 64-bit OS X applications) you only need to declare properties and can leave out declaring the ivars inside the interface block. According to this answer in a similair thread it would be for debugging purposes. But are there any other benefits except for debugging that you would use this approach?

Cheers,

Peter

like image 894
Peter Warbo Avatar asked May 23 '11 15:05

Peter Warbo


3 Answers

Explicitly declaring ivars gives you the possibility to internally use a specialized type for the ivar.

A typical example is an internally mutable object that can be accessed from outside in a readonly, immutable way.

Example:

@interface Foo : NSObject
@property (readonly) NSArray *bars;
@end

@implementation
{
    NSMutableArray *bars;
}

@synthesize bars;

- (void)addBar:(Bar *)bar
{
    [bars addObject:bar];
}
@end

Of course the object returned from the bars property is not really immutable. But the point is that the API does not reveal its mutability.

Note that I used the fancy new private-ivars-in-implementation style. It's depending on the modern runtime as well as the clang compiler.

like image 97
Nikolai Ruhe Avatar answered Nov 18 '22 23:11

Nikolai Ruhe


Some programmers like to define their iVars with a slightly different name to differentiate between direct access and KVC access. For example:

in the .h

@interface ViewController : UIViewController {
    UITableView *_table;
}

@property (nonatomic, retain) IBOutlet UITableView *table;

and in the .m

@synthesize table = _table;

this way you directly access the iVar using _table but you use the synthesized setters and getters using [self table]

like image 23
Abizern Avatar answered Nov 19 '22 00:11

Abizern


But are there any other benefits except for debugging that you would use this approach?

i declare the ivars explicitly for:

  • access control (visibility)
  • organization
  • uniform written style
  • compatibility (hey, this program could support 32 bit one day)
  • and because i associate properties as a part of the class's public interface (although exceptions to this exist) - not simply as accessors to the class's ivars.

"everything as a read/write property" is fundamentally flawed ood.

like image 30
justin Avatar answered Nov 19 '22 00:11

justin