4

Possible Duplicate:
iOS: must every iVar really be property?

I just read a book that said that modern convention is not to declare any ivars at all in your .h file between curly braces, and instead to make everything properties.

I want to make sure this is true even in trivial cases. I am making a class where there is a BOOL named "recording" which says whether the device is currently recording some video. This isn't something that other classes need, and my incline is to just put it as a BOOL in the header then refer to it in the .m file in the 2 spots where it is needed.

However, I also want to do things the accepted, right way. But I don't see why I make it a public property?

Community
  • 1
  • 1
Cocorico
  • 2,319
  • 3
  • 22
  • 31
  • I keep seeing 'the book', 'a book', 'some book'.... Which book was it exactly? I want the title in order to look into this further, and maybe even expose this charlatan for misguidance on a mass scale ;\ – eric Jan 27 '13 at 13:26

5 Answers5

8

What you read is wrong, plain and simple.

Modern convention is to skip ivars when there is a corresponding property that can synthesize them. Additionally, with recent versions of LLVM it is possible to move your ivars to your implementation file (as @DrummerB has already mentioned) so that the header contains no ivars. That's considered good practice because it doesn't expose internal workings of the class.

But have no ivars at all and a property for everything that was an ivar? Nope, not normal Objective-C.

Jonathan Grynspan
  • 43,286
  • 8
  • 74
  • 104
  • I didn't realize, the book suggested using properties for *everything*, wow, good point. – DrummerB Oct 10 '12 at 14:43
  • Ivars are still preferred for private data. Properties are preferred for public data. – Jonathan Grynspan Oct 10 '12 at 15:02
  • 2
    The modern convention is changing; more and more of the projects I'm involved in use `@property` to declare everything, including things that are only ever accessed through `_ivar` because `@property` captures more intention with the additional attributes. Not saying that this answer is wrong, just that convention is continually evolving as the language evolves. – bbum Oct 10 '12 at 16:10
  • @bbum: The convention is changing, yes, but it hasn't changed that much yet. – Jonathan Grynspan Oct 10 '12 at 17:09
5

Your book is right (and wrong). Don't declare ivars in your headers anymore. That's only supported for compatibility reasons. But also don't declare properties for private variables.

If you want do declare a private ivar that other classes don't need to use, declare them in your implementation file:

// MyClass.m
@implementation {
    BOOL recording;
}

// methods

@end
DrummerB
  • 39,814
  • 12
  • 105
  • 142
  • +1 for declaring ivars in '@implementation{}' instead of in '@interface MyClass(){}' as I was accustomed do doing. Learned a new way. – eric Jan 27 '13 at 13:20
2

I recommend to not use ivar at all. Instead you can create a class extension in which you will declare properties that has to be hidden:

@interface MyClass ()

@property (nonatomic, assign) BOOL recording;

@end
iSofTom
  • 1,718
  • 11
  • 15
  • For objects I would do this too. But isn't that a bit an overhead for something as simple as a BOOL flag? – DrummerB Oct 10 '12 at 14:50
  • That's what i thought too, but to have an evolutive code it's a good idea because maybe tomorrow your BOOL will be an NSNumber – iSofTom Oct 10 '12 at 14:54
  • 1
    or you want to broadcast something vie NSNotificationCenter or delegation once that bool switches. than it is easy to do it by creating a custom setter. – vikingosegundo Oct 10 '12 at 14:55
  • Of course. You can always make it a (internal) property. But OP is just using it a simple flag. No need for accessors there imho. – DrummerB Oct 10 '12 at 15:05
  • Honest question; Is it really that much overhead? My understanding is that all it does is generate simple getters and setters for non-object properties. Is a few lines of code really going to be that big of a deal? – Dcritelli Oct 10 '12 at 15:52
1

You could use something like

@interface G4AppDelegate ()

@property (nonatomic, assign) BOOL recording;

@end

To make an "internal" property.

Or as the other answer states use an iVar in your implementation

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
Martin
  • 747
  • 6
  • 11
0

Some books explain that you should only use getter and setter to access your ivar, even if they are private. This is a little too psychotique to me.

Before clang, u should have to create category on class and use synthesizer to make ur ivar private. like this:

@interface AppDelegate ()
@property(nonatomic, assign)int aValue;
@end

// + @implement AppDelegate // @synthetise aValue;

that could be annoying since sometime u need some simple ivar, without any getter/setter control. And u're adding code where there is no need.

Now with clang you can put ur ivar directly on implementation file like this in ur code:

@interface AppDelegate (){
  int _aValue;
}
@end

And u're hiding private ivar out of the scope the header. Note, u can't compile this with gcc.

Mr Bonjour
  • 3,330
  • 2
  • 23
  • 46
  • you dont need to define a Class Extension to add internal ivars anymore, you can ad them to the main implementation (although I usually add them to an extension, as I find it "cleaner") – vikingosegundo Oct 10 '12 at 14:58