0

For example, in the following codes.

@interface TUTViewController : UIViewController
{
   NSTimer *timer;
} 
@end

and

@interface TUTViewController : UIViewController

@property (weak, nonatomic) NSTimer *timer;

@end

In which scenario do we use the first method to declare variable?

jscs
  • 63,694
  • 13
  • 151
  • 195
user3586299
  • 153
  • 1
  • 2
  • 10
  • 3
    Declare a property if you want to control get / set logic. Also the equivalent property to the ivar you have would be strong not weak. – Kevin DiTraglia Jun 06 '14 at 16:34
  • 1
    Never put ivars in the .h. ivars should always be private meaning they do not belong in the public .h. If you create ivars, put them in the .m file. – rmaddy Jun 06 '14 at 16:42
  • I'd say almost never. For objC types always try to use properties. If you need to use the ivar from your implementation you can do it anyway. I saw objC types because I've had problems using C++ references as properties, for example. – Fernando Mazzon Jun 06 '14 at 16:54
  • 1
    This is very much a religious issue. – Hot Licks Jun 06 '14 at 17:24

2 Answers2

2

You are going to get lots of opinions on this, often stated as hard fast rules.

Example:

Maddy: Never put ivars in the .h. ivars should always be private meaning they do not belong in the public .h. If you create ivars, put them in the .m file

I have tremendous respect for Maddy, but I disagree with him on this one.

If you put your iVars in your .m file, they are hidden from other classes, but they are also hidden from subclasses that you create.

I prefer to mark my instance variables as @protected, which makes them available to subclasses, but not to other classes.

Others will tell you to make EVERYTHING a property. Before ARC, it made sense to save all your objects in properties, since you could use the setter on the property to manage the memory on your objects. (When assigning a value to a retained property, the setter would first release any old value, then retain the new value.) Now ARC takes care of that for you even for iVars, so the argument for making everything a property is less.

What I do is to make everything an iVar, unless:

  1. I need a custom getter or setter method with special behavior.
  2. I want to access the value from another object.
  3. I need to mark a property as "atomic" for access from another thread. (get in the habit of declaring all of your properties as "nonatomic." If you don't know what atomic is for for, you want nonatomic. Atomic properties are slower than nonatomic.)

As a matter of policy I NEVER access another object's iVars except trough a property.

There is a small but real amount of overhead in using a property rather than an instance variable. A property read/write always makes a method call. An iVar accesses the memory directly without the overhead of a method call. Usually the difference is too small to matter. But, if you're doing millions of operations, like doing something to every pixel in a large image, or handling callbacks from processing video or audio samples in real-time, the difference can be large.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 1
    Subclasses should not have access to the ivars of a superclass. It breaks encapsulation. There is a reason why we don't have access to ivars in the Apple classes we all extend. It is so things don't break. Follow the same guidelines in your own classes. Protected ivars is a poor design choice and makes your class hierarchy fragile. – rmaddy Jun 06 '14 at 17:58
0

I would highly suggest to use @properties unless there is a very good reason not to. It's true the discussion is a religious one more than a technical one but since we are probably all followers of the Cult of Mac, if Apple prefers you to use @properties then that's the standard. In my opinion both Apple documentation and Xcode aren't as pushy on standards like ReSharper would do in Visual Studio for instance (it warns when you don't use var for example). That's a pity because that would make it easier for me to pick up code after somebody else.

There is a way to "hide" @properties in a .m file, you should declare it as follows:

@interface ABCMySpiffyClass ()

@property (weak, nonatomic) IBOutlet UIImageView *spiffyImage;
@property (weak, nonatomic) IBOutlet UILabel *spiffyTitle;

@end

These are not completely private to another consumer of your class but it is hidden at first sight. This should tell the other developer that he or she should not use them. I think public/private has more to do with documentation as it has to do with application security for most apps.

Lucas van Dongen
  • 9,328
  • 7
  • 39
  • 60