Ios: Usage of Self and Underscore(_) with Variable

iOS: Usage of self and underscore(_) with variable

I think it helps to consider how properties are (or might be) implemented by the compiler.

When you write self.users = array; the compiler translates this to [self setUsers:array];
When you write array = self.users; the compiler translates this to array = [self users];

@synthesize adds an ivar to your object (unless you added it yourself), and implements the -users and -setUsers: accessor methods for you (unless you provide your own)

If you're using ARC, -setUsers: will look something like:

- (void)setUsers:(NSArray *)users
{
_users = users; // ARC takes care of retaining and release the _users ivar
}

If you're using MRC (i.e. ARC is not enabled), -setUsers: will look something like*:

- (void)setUsers:(NSArray *)users
{
[users retain];
[_users release];
_users = users;
}

* - Note that this is a simplified, nonatomic implementation of -setUsers:

How does an underscore in front of a variable in a cocoa objective-c class work?

If you use the underscore prefix for your ivars (which is nothing more than a common convention, but a useful one), then you need to do 1 extra thing so the auto-generated accessor (for the property) knows which ivar to use. Specifically, in your implementation file, your synthesize should look like this:

@synthesize missionName = _missionName;

More generically, this is:

@synthesize propertyName = _ivarName;

IOS: property and self

If I use a property, must I also use the simple declaration in interface?

No, generally you just want to use the @property (it will quietly add an instance variable for you).

If I use my_string as a property, must I always use self. before?

You don't need to but you should. Using self. calls the accessor method to get the variable contents. Not using self. accesses the instance variable directly. So, if you add a custom accessor in the future you will need to refactor.

Often you will reuse the same variable multiple times. In this case, call self., but use it to set a local variable that you then use throughout the method (in this way the accessor is only called once).

If I use a property, is it necessary to write @synthesize for each? (because I saw that sometimes it's not necessary.

No, the compiler will add:

@synthesize propertyName = _propertyName;

for you, and that is a good approach to follow (separating the property name from the instance variable name).

Assigning a Variable to an Underscore in Swift

This test shows that the object is created and then destroyed when the object goes out of scope:

class ToDoItem {
var title = ""

init(title: String) {
self.title = title
}

deinit {
print("deinit \(title)")
}
}

func test() {
print("test")

_ = ToDoItem(title: "First")
_ = ToDoItem(title: "Second")

print("end test")
}

func callTest() {
print("calling test()...")
test()
print("back from test()")
}

callTest()

Output:

calling test()...
test
end test
deinit Second
deinit First
back from test()

Extended test:

func test() {
print("test")

_ = ToDoItem(title: "Item 1")
for i in 2...4 {
_ = ToDoItem(title: "Item \(i)")
}
_ = ToDoItem(title: "Item 5")

print("end test")
}
calling test()...
test
deinit Item 2
deinit Item 3
deinit Item 4
end test
deinit Item 5
deinit Item 1
back from test()

Notice that items 2, 3 and 4 are deinitialized as they go out of scope in each loop. Items 1 and 5 are deinitialized when they go out of scope when test() completes.


Inside of an App

As Dmitry Plotnikov noted in his answer, the above is true only in a Swift Playground. In an app, the results are:

calling test()...
test
deinit Item 1
deinit Item 2
deinit Item 3
deinit Item 4
deinit Item 5
end test
back from test()

That tells us:

  1. The objects are created.
  2. They are freed immediately.

When do you make an underscore in front of an instance variable?

A lot of people use this for private variables, to differentiate between private variables and public variables within an object.

It is a completely optional way of working.

What's the difference between _variable & self.variable in Objective-C?

The difference is that:

the variable names with _ 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

Does let _ = ... (let underscore equal) have any use in Swift?

You will get a compiler warning if the method has been marked with a warn_unused_result from the developer documentation:

Apply this attribute to a method or function declaration to have the compiler emit a warning when the method or function is called without using its result.

You can use this attribute to provide a warning message about incorrect usage of a nonmutating method that has a mutating counterpart.



Related Topics



Leave a reply



Submit