Difference between using self.variable and _variable when init these variables [duplicate]

StackOverflow https://stackoverflow.com/questions/21844620

  •  13-10-2022
  •  | 
  •  

سؤال

I know instance variable and property. I often see people init a UILabel like this

self.label = [[UILabel alloc] init]; //and 
_label = [[UILabel alloc] init];

So, what's the difference between using self.label and _label to set a object?

هل كانت مفيدة؟

المحلول

The difference is simple: Using self.label = [[UILabel alloc] init] will actually invoke the method [self setLabel:[[UILabel alloc] init]], and using _label = [[UILabel alloc] init] will directly assign the value to the instance variable.

In practice what this means is that using the dot syntax is usually the best as the method invoked probably handles a lot of stuff for you, including:

  • Memory management: For example, if you declare a property with attribute 'strong' or 'retain', then the method invoked should retain the object assigned.
  • Key-Value Coding notifications: Maybe the class is key-value coding compliant for the property, which means the invoked method will notify the changes to observer objects.

Why would you not use the dot syntax? There are two potential reasons:

  • To avoid side effects: A good practice is to not use the dot syntax inside an initializer method. This is because we want to assign the value but don't want the other side effects of the invoked method for safety reasons.
  • Performance: This is probably rare, but maybe you are trying to implement a method with high performance and using instance variables directly can save the cost of invoking a method.

If you want to know more, I recommend reading this iOS guide which describes in more detail the ideas I mention here.

نصائح أخرى

The difference is that:

the names with _variable are instance variables.

self.variable is calling a getter method on your object.

In your example, the instance variables are automatically generated and you don't need to synthesize your properties either.

The real important difference in your example comes into play if you are not using ARC-

self.variable will retain an object for you if you mark the property with retain or strong _variable does not address memory management at all

In your example, self.label would call the getter method 'label' on self -- this is equivalent to calling [self label]. _label is the backing store for the class instance property -- i.e. an instance variable, no different than accessing a standard variable directly. There is no getter method wrapped around it.

The difference is very, very important, because you are able to override the getter/setter methods for properties. You may wish to do this, for e.g., if you would like to bundle some behavior change with the state change of the variable. Calling the getter or setter maintains this behavior. Calling the getter also retains the variable.

Basically, unless you know why you're preferring to class _label in any particular instance, stick with the getter self.label. One case where you may want to use _label is during initialization, where you need to set a happy default w/o behavior the getter may bring with it.

The difference is that using _label is accessing the instance variable (ivar for short) directly, where as using self.label is actually calling [self setLabel:[[UILabel alloc] init]];.

Calling the setLabel: method does other things, such as possibly retaining the variable (depending on how the property was declared), but can also trigger other side effects as set up in your setLabel: method. Those side effects could be something like data validation, or could perhaps sync that value to a server.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top