_variable vs variable name

I have created some UILabels and UITextFields. Let's say my Label is named "weight".


When I am referrencing it, I have to use _weight. If I synthesize weight to equal _weight I don't need the underscore.


Is there anything wrong with leaving the underscore to reference the variables, or is this a bad practice?

Yes it is bad practice. Use self.weight. You should never refer to a property's backing instance variable directly except in initializers, getters or setters. IMHO

Definitely agree. An important part of good code design is good encapsulation—making sure that individual pieces of code can only read and modify information that is directly relevant to their jobs.

Can I ask a dumb question here?

If in my .h file I have a simple

IBOutlet UILabel *weight;

then I can reference the object "weight" without needing "self.weight" or "_weight". Why isn't that the prefered way of referencing weight within the class?

You're referring to Objective-C, right? In Swift, it's perfectly fine to just use the property name because "self." is implied, but in your case, I believe that you are unintentionally accessing the instance variable instead of the property—by default it's synthesized as `weight` instead of `_weight`. Try adding the following declaration inside your @implementation to see if I'm right:

@synthesize weight = _weight


Oh, and why do you have a UILabel named "weight"? Shouldn't it be "weightLabel" or something that describes a label, not the model property of weight?

Whoops—forgot the semicolon there. I meant to write:

@synthesize weight = _weight;


I've become too familiar with Swift, I guess 😁

Yes, Objective-C.

I still don't get it. What do you mean by " you are unintentionally accessing the instance variable instead of the property" and what is the effect of doing that? Can you give me an example of code that does something different when it refers to weightLabel rather than _weightLabel. For example, this works just fine with a simple "IBOutlet UILabel *weightLabel;" in the .h


weightLabel.text=@"Hi User"; // sets the label text

or

NSString *theText=weightLabel.text; // sets a local variable theText to "Hi user".


What is the purpose of _weightLabel or self.weightLabel when weightLabel works fine?

In Objective-C, it's best to always use accessors (getters/setters) when working with instance variables. If you directly access those instance variables, you will often bypass KVO (key-value observation).


Furthermore, it's much more difficult to debug since you'd cant just set up a single breakpoint in a getter/setter.

All of what rsharp said is good advice. The point of the underscore in front of the name is to reinforce the point that you're not supposed to be using it directly all over your code—only within the accessor methods. Within a class, encapsulation is not a tremendous issue, but it's generally a better idea to use the accessor for everything because that way if you need to perform customization or other work (including KVO and notifications and such), you can catch it every time the value is read or set. Imagine the debugging frustration if you had to track down one or two places where that customization was being accidentally bypassed! Of course, most of the time (especially with outlets) this isn't going to be a problem, but it's good to be in the habit.

Personally, I hate the fact that "self." is optional when accessing properties. I wish it were required so you would never have to go look somewhere else in the code to see if you're referring to a local variable or a property.

But if we are referencing a UILabel within the class isn't that a variable within the class and not a property of the class? If so, are you agreeing it should be referenced as weightLabel?

The following has suited my needs very well over the years and for numerous languages:


All property names are suffixed with _II (guarantees I will never collide with any Apple symbols, especially in subclasses of Apple-supplied classes). Examples:

  • currentValue_II
  • isLoaded_II


All function arguments are prefixed with 'a' or 'an':

  • aURL
  • anElementArray


All local variables are prefixed with 'the':

  • theNumberOfItems
  • theBackgroundColor


Even if I didn't take the extreme case of suffixing properties with my company initials, I could still tell them apart from function arguments and local variables since they are never prefixed with 'a', 'an' or 'the'

I used to do something similar in my Java days - instance members had a single underscore suffix, class members a double underscore, local variables no suffix. I didn't go as far as differentiating method parameters from local variables.


PBK, I myself always use self.weightLabel in Objective-C, and wish that were the required way to do it. It's just a style / preference thing really, but it makes things clearer in my opinion. In Swift the overwhelming consensus on style seems to be to omit the "self." so I grudgingly go along with that. Personally I believe the push to omit anything and everything the compiler doesn't need in an attempt to make the code "simpler" is misguided. If you go too far in that direction you get to perl. For example I prefer having to explicitly declare types rather than have the compiler infer it. With "let foo = bar" you have no clue what the type of "foo" is. Sure if you're in an IDE with tool tips & syntax highlighting & shortcuts to jump to the declaration it helps, but code is often found on web sites, forums and printed out and then you have to go looking somewhere else instead of having the type right there.


We are getting a bit off topic though 🙂

_variable vs variable name
 
 
Q