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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With