It's now more than 5 months that I'm in Objective-C, I've also got my first app published in the App Store, but I still have a doubt about a core functionality of the language.
When am I supposed to use self accessing iVars and when I'm not?
When releasing an outlet you write self.outlet = nil in viewDidUnload, instead in dealloc you write [outlet release]. Why?
When you write self.outlet = nil the method [self setOutlet:nil]; is called. When you write outlet = nil; you access variable outlet directly.
if you use #synthesize outlet; then method setOutlet: is generated automatically and it releases object before assigning new one if you declared property as #property (retain) NSObject outlet;.
Very very important blog to understand about properties getter-setter method in objective c
Understanding your (Objective-C) self
http://useyourloaf.com/blog/2011/2/8/understanding-your-objective-c-self.html
You use self when you are refering to a #property.
Usually it will have been #synthesize'd.
You do not use self if you are refering to a "private" variable. Typically, I use properties for UI elements such as UIButtons or for elements I want easily reachable from other classes.
You can use the #private, #protected modifiers to explicitly enforce visibility. You cannot however use private methods, that do not exist in Objective-C.
The part about nil, release and dealloc is unrelated to the use of "self". You release what you retained, you nil what is autoretained.
You should read the Objective-C guide, it's well written and very enlightening.
You use self. when you're accessing properties of class that you're in (hence self). Basically you use self when you want to retain a value, but is only when you have retain in your property definition.
release just releases object that you've retained. You shouldn't release something that you haven't retained cuz it will lead to crash (zombie object).
Related
What are the differences between strong and weak in #property declarations of pointers to objects?
Also, what does nonatomic mean?
It may be helpful to think about strong and weak references in terms of balloons.
A balloon will not fly away as long as at least one person is holding on to a string attached to it. The number of people holding strings is the retain count. When no one is holding on to a string, the ballon will fly away (dealloc). Many people can have strings to that same balloon. You can get/set properties and call methods on the referenced object with both strong and weak references.
A strong reference is like holding on to a string to that balloon. As long as you are holding on to a string attached to the balloon, it will not fly away.
A weak reference is like looking at the balloon. You can see it, access it's properties, call it's methods, but you have no string to that balloon. If everyone holding onto the string lets go, the balloon flies away, and you cannot access it anymore.
A strong reference (which you will use in most cases) means that you want to "own" the object you are referencing with this property/variable. The compiler will take care that any object that you assign to this property will not be destroyed as long as you point to it with a strong reference. Only once you set the property to nil will the object get destroyed (unless one or more other objects also hold a strong reference to it).
In contrast, with a weak reference you signify that you don't want to have control over the object's lifetime. The object you are referencing weakly only lives on because at least one other object holds a strong reference to it. Once that is no longer the case, the object gets destroyed and your weak property will automatically get set to nil. The most frequent use cases of weak references in iOS are:
delegate properties, which are often referenced weakly to avoid retain cycles, and
subviews/controls of a view controller's main view because those views are already strongly held by the main view.
atomic vs. nonatomic refers to the thread safety of the getter and setter methods that the compiler synthesizes for the property. atomic (the default) tells the compiler to make the accessor methods thread-safe (by adding a lock before an ivar is accessed) and nonatomic does the opposite. The advantage of nonatomic is slightly higher performance. On iOS, Apple uses nonatomic for almost all their properties so the general advice is for you to do the same.
strong: assigns the incoming value to it, it will retain the incoming value and release the existing value of the instance variable
weak: will assign the incoming value to it without retaining it.
So the basic difference is the retaining of the new variable.
Generaly you want to retain it but there are situations where you don't want to have it otherwise you will get a retain cycle and can not free the memory the objects. Eg. obj1 retains obj2 and obj2 retains obj1. To solve this kind of situation you use weak references.
A dummy answer :-
I think explanation is given in above answer, so i am just gonna tell you where to use STRONG and where to use WEAK :
Use of Weak :-
1. Delegates
2. Outlets
3. Subviews
4. Controls, etc.
Use of Strong :-
Remaining everywhere which is not included in WEAK.
strong and weak, these keywords revolves around Object Ownership in Objective-C
What is object ownership ?
Pointer variables imply ownership of the objects that they point to.
When a method (or function) has a local variable that points to an object, that variable is said to own the object being pointed to.
When an object has an instance variable that points to another object, the object with the pointer is said to own the object being pointed to.
Anytime a pointer variable points to an object, that object has an owner and will stay alive. This is known as a strong reference.
A variable can optionally not take ownership of an object that it points to. A variable that does not take ownership of an object is known as a weak reference.
Have a look for a detailed explanation here Demystifying #property and attributes
Here, Apple Documentation has explained the difference between weak and strong property using various examples :
https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/EncapsulatingData/EncapsulatingData.html#//apple_ref/doc/uid/TP40011210-CH5-SW3
Here, In this blog author has collected all the properties in same place. It will help to compare properties characteristics :
http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html
strong is the default. An object remains “alive” as long as there is a strong pointer to it.
weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
To understand Strong and Weak reference consider below example, suppose we have method named as displayLocalVariable.
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
}
In above method scope of myView variable is limited to displayLocalVariable method, once the method gets finished myView variable which is holding the UIView object will get deallocated from the memory.
Now what if we want to hold the myView variable throughout our view controller's life cycle. For this we can create the property named as usernameView which will have Strong reference to the variable myView(see #property(nonatomic,strong) UIView* usernameView; and self.usernameView = myView; in below code), as below,
#interface LoginViewController ()
#property(nonatomic,strong) UIView* usernameView;
#property(nonatomic,weak) UIView* dummyNameView;
- (void)displayLocalVariable;
#end
#implementation LoginViewController
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)viewWillAppear:(BOOL)animated
{
[self displayLocalVariable];
}
- (void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#end
Now in above code you can see myView has been assigned to self.usernameView and self.usernameView is having a strong reference(as we declared in interface using #property) to myView. Hence myView will not get deallocated from memory till self.usernameView is alive.
Weak reference
Now consider assigning myName to dummyNameView which is a Weak reference, self.dummyNameView = myView; Unlike Strong reference Weak will hold the myView only till there is Strong reference to myView. See below code to understand Weak reference,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.dummyNameView = myView;
}
In above code there is Weak reference to myView(i.e. self.dummyNameView is having Weak reference to myView) but there is no Strong reference to myView, hence self.dummyNameView will not be able to hold the myView value.
Now again consider the below code,
-(void)displayLocalVariable
{
UIView* myView = [[UIView alloc] init];
NSLog(#"myView tag is = %ld", myView.tag);
self.usernameView = myView;
self.dummyNameView = myView;
}
In above code self.usernameView has a Strong reference to myView, hence self.dummyNameView will now have a value of myView even after method ends since myView has a Strong reference associated with it.
Now whenever we make a Strong reference to a variable it's retain count get increased by one and the variable will not get deallocated till it's retain count reaches to 0.
Hope this helps.
Strong: Basically Used With Properties we used to get or send data from/into another classes.
Weak: Usually all outlets, connections are of Weak type from Interface.
Atomic: Such type of properties are used in conditions when we don't want to share our outlet or object into different simultaneous Threads. In other words, Atomic instance make our properties to deal with one thread at a time.
Hopefully it helpful for you.
I have a #class Foo which contains a __weak id bar ivar. Several actions from methods in different classes can cause the object to disappear and thus get bar niled.
I want to perform an action when the ivar is automatically niled by ARC.
If possible, I would want to avoid turning bar into a property or using Key-Value Observing.
Is this even possible? If not, can KVO be used against non-property ivars?
I was led here by a duplicate question, here is what I answered:
You can't do that with KVO, but you can still get a notification and emulate this by associating an object with your iVar using objc_setAssociatedObject(), it will be deallocated when the weak variable dies.
#interface WeakObjectDeathNotifier : NSObject
#end
#implementation WeakObjectDeathNotifier
- (void)dealloc
{
// the code that shall fire when the property will be set to nil
}
#end
You can build on top of that very elaborate notifiers, using NSNotificationCenter or just custom blocks, depending on how heavily you rely on that for a specific ivar case or for lots of them.
The good thing about this solution is that it works with any __weak ivar, even if you don't control the type the __weak ivar has.
KVO cannot be successfully used on non-property IVARs.
You cannot detect from the runtime when Objective-C's ARC nils an IVAR.
I suggest to override dealloc. If you know the type of the object that will be allocated, and it's a custom class (otherwise subclass it), you can perform the action when the object is deallocated, which is exactly what happens when ARC sets the retain count to zero and sets the weak variable to nil.
I'm was playing around with the standard sample split view that gets created when you select a split view application in Xcode, and after adding a few fields i needed to add a few fields to display them in the detail view.
and something interesting happend
in the original sample, the master view sets a "detailItem" property in the detail view and the detail view displays it.
- (void)setDetailItem:(id) newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
i understand what that does and all, so while i was playing around with it. i thought it would be the same if instead of _detailItem i used self.detailItem, since it's a property of the class.
however, when i used
self.detailItem != newDetailItem
i actually got stuck in a loop where this method is constantly called and i cant do anything else in the simulator.
my question is, whats the actual difference between the underscore variables(ivar?) and the properties?
i read some posts here it seems to be just some objective C convention, but it actually made some difference.
_property means you are directly accessing the property.
self.property means you are using accessors.
In your case, in the setter method you are calling it, creating a recursive call.
In the course of your experiment, you've set up an endless loop which is why the simulator goes non-responsive.
Calling self.detailItem within the scope of setDetailItem: calls setDetailItem: recursively since your class implements a custom setter method for the property detailItem.
I would refer you to the Apple documentation on declared properties for the scoop on properties, ivars, etc; but briefly, declared properties are a simplified way of providing accessor methods for your class. Rather than having to write your own accessor methods (as we had to do before Objective-C 2.0) they are now generated for you through the property syntax.
The properties are basically a way of the compiler to generate a setter and getter for a given instance variable.
So when you use something like:
id detailItem = self.detailItem;
what you are doing under the hood is:
id detailItem = [self detailItem];
Same for:
self.detailItem = otherDetailItem;
would be:
[self setDetailItem:otherDetailItem];
So when you write the setter yourself.. you get in an infinite loop since you access the method itself in itself.
You can freely make use of the 'self.' notation in your class, just not when you're overriding the setter or accessor because of the mechanism I described above.
Cases in a class where I use the . notation over simply accessing the ivar is when I change the value, you never know inside your class what needs to happen when you change the value. do you have something in terms of a status that should notify some delegate that a status changed? Usually this is not the case, however, just by using the . notation you are making sure that in the future you won't have to refactor some code if you did decide to do some magic in your setter method.
I'll make an example (without ARC enabled):
#property (nonatomic, retain) NSNumber* number;
If you don't synthesize it, you can access it this way:
self.number= [NSNumber numberWithBool: YES];
This case the number is retained.If instead you synthesize it and don't use the property:
#synthesize number;
Later in the file:
number=[NSNUmber numberWithBool: YES];
You haven't used the property, so the number is not retained.That makes a relevant difference between using accessors and synthesized properties.
I had a library designed for ARC and iOS 5, but a customer wanted to build for iOS 4.x. I converted properties with the weak qualifer to unsafe_unretained, however now it seems I am running into memory corruption-esq crashes.
In the case of the crash, I have a delegate property like this
#property (unsafe_unretained) id<MYDelegateProtocol> delegate;
and I #synthesize the ivar.
whenever I want to call a method on the delegate, I check if it is nil, and if it is not, then I call the method, since I have no optional methods in that protocol, I don't check respondsToSelector.
However, since changing the weak to unsafe_unretained, I have found that apparently the reference goes away, and I am left with a dangling pointer. If I put a breakpoint on ObjC Exceptions, (for unrecognized message), and then po the address of the object, I see that it is an object that is not even implementing the protocol of the delegate, so of course it crashes.
When using unsafe_unretained how can I know that the reference has "gone away"? My code relied on the pointer being zeroed out before.
You have an object ownership problem. An object that has been released won't be nil, it would just be pointing at the address where the object used to be. An nil pointer would point to 0x0. You need to analyze how come your architecture has a delegate that is being released while the record being delegated is alive. On some special circumstances, objects being delegated might retain their delegates (like NSURLConnection). On other cases, objects being delegated are a property of their delegates, in which case, the delegation needs to be cleared out before deallocation. Analyze your pattern and/or provide more information.
Try this class I developed iOSWeakForwarder
When using unsafe_unretained how can I know that the reference has
"gone away"? My code relied on the pointer being zeroed out before.
This has to be determined at compile time by you. Often, the object that is the delegate should set the delegate property of the object delegating to it to nil in the dealloc method. For example:
- (void)dealloc
{
if (_httpRequest.delegate == self)
_httpRequest.delegate = nil;
}
Hope this helps!
If I add a property to the ViewController
#property (strong, atomic) UIView *smallBox;
and synthesize it in the .m file, the variable can actually be referenced just by smallBox inside of any instance methods.
But then, self.view cannot be replaced by view, even though view is defined as a property of UIViewController too. Why the difference and what is the rule?
self.view and view/_view are not the same thing. Depending on how you create your instance variables, view or _view refer to the actual object instance variable. It is dangerous to access this directly, and you should only do so in init, dealloc or in accessors. Everywhere else, you should use self.view.
self.view is exactly the same as [self view], which passes the message "view" to the object "self" an returns the result. By default, when an object receives a message, it executes the method with that name, and the default implementation of view will return the value of the related instance variable (either view or _view).
In older versions of Xcode, #synthesize view would create an instance variable called view. In the latest versions of Xcode, declaring a property view will will automatically create an instance variable called _view in many cases, even without #synthesize. This change makes it easier to notice when you are accessing the ivar directly.
In short:
except in init, dealloc and the view accessors (if you custom write them), always use self.view.
In those methods, you should refer to it as _view.
If you are writing for the latest Xcode, do not include #synthesize at all. If you are writing for a slightly older Xcode, use #synthesize view=_view;
self.view does not mean "the value of the instance variable." It means "the result of passing the message 'view'" which is generally implemented as returning the instance variable.
You can't access the view member directly because it's declared as #package visibility in UIViewController. This prevents your code from accessing it. (Normally, you wouldn't want to access instance variables of your superclasses directly anyway.)
For your class's own properties, you can access the instance variable directly, but you need to be aware of the memory management implications of this. (As well, as Rob points out, as any other behaviours you're side-stepping by avoiding the accessor.)
Apple defined properties usually contain an underscore before their name, so when you use self.view, it is actually getting the instance variable _view from the object. You cannot use _view in code, as it will cause a linker error on compiling, but Xcode will still highlight it for you. Another way of accessing the instance variable for self.view is by self->_view, but again, this causes a linker error. The reason for these linker errors is because the compiled libraries do not contain the symbols for _view; even if its declaration can be found in UIViewController.h.