Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to access property with self and when not to?

Can anyone explain the difference between setting someObject = someOtherObject; and self.someObject = someOtherObject; if someObject is a class property created with @property (nonatomic, retain) SomeType someObject;

To clarify I have something like:

@interface SomeClass : NSObject {
   SomeType* someObject;
}

@property (nonatomic, retain) SomeType* someObject;

@end

I have noticed I get EXC_BAD ACCESS sometimes when I use the property without self and it seems quite random. When I use self my program acts as it should be. I don’t get any compiler errors or warnings when I skip self so I guess it is somehow valid syntax?

like image 948
picknick Avatar asked Feb 03 '11 09:02

picknick


People also ask

When would you use self in a method?

You use self when: Defining an instance method. It is passed automatically as the first parameter when you call a method on an instance, and it is the instance on which the method was called. Referencing a class or instance attribute from inside an instance method.

When should I use self in Swift?

Outside of initializers, the main reason for using self is because we're in a closure and Swift requires it so we're clear we understand what's happening. This is only needed when accessing self from inside a closure that belongs to a class, and Swift will refuse to build your code unless you add it.

Do I need to use self in Swift?

The self keyword is usually not required. The only times you should use self is: To differentiate a property from a local variable that has the same name. Reference a property inside a closure.

What does self mean in Swift?

In Swift self is a special property of an instance that holds the instance itself. Most of the times self appears in an initializer or method of a class, structure or enumeration. The motto favor clarity over brevity is a valuable strategy to follow.


1 Answers

self.someObject = someOtherObject makes use of the property. Properties generate setters and getters for you. In your case, you gave the retain attribute to the property, which means that an object set via this property will automatically receive a retain message which increases its retain count by 1. Additionally, the old value of the member variable is sent a release message which decreases its retain count.

Obects are being deallocated, when their retain count reaches 0. You get an EXC_BAD_ACCESS ecxeption if you try to access a deallocated object (e.g. if you try to release it too often).

In your case:

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
self.someObject = soo; //soo's retain count is now 2
[soo release]; //soo's retain count is 1 again, as self still uses it.
[self doSomethingWithSoo];

However, if you do not use the setter, you must not release soo.

SomeOtherObject *soo = [[SomeOtherObject alloc] init]; //retain count: 1
someObject = soo; //soo's retain count is still  1
[soo release]; //soo's retain count is 0, it will be deallocated
[self doSomethingWithSoo]; //will fail with an EXC_BAD_ACCESS exception, as soo does not exist anymore.
like image 173
Björn Marschollek Avatar answered Sep 26 '22 16:09

Björn Marschollek