I've seen a number of posts related to delegates, and I would like to know the proper way to reference them. Suppose I have an object declared like:
#interface MyViewController : UITableViewController {
id delegate;
}
#property (nonatomic, retain) id delegate;
#end
Through the lifecycle of MyViewController, it will make calls to methods of its delegate in response to interaction with the user.
When it's time to get rid of an instance of MyViewController, does the delegate ivar need to be release'ed in the implementation's dealloc method since it is declared with retain?
Or conversely, should delegate even be retained? Perhaps it should be #property (nonatomic, assign) id delegate? According to Apple's docs:
retain ... You typically use this attribute for scalar types such as NSInteger and CGRect, or (in a reference-counted environment) for objects you don’t own such as delegates.
Normally I'd just go with what the docs say, but I've seen a lot of code that calls retain on a delegate. Is this just "bad code?" I defer to the experts here... What is the proper way to handle this?
You generally want to assign delegates rather than retain them, in order to avoid circular retain counts where object A retains object B and object B retains object A. (You might see this referred to as keeping a "weak reference" to the delegate.) For example, consider the following common pattern:
-(void)someMethod {
self.utilityObject = [[[Bar alloc] init] autorelease];
self.utilityObject.delegate = self;
[self.utilityObject doSomeWork];
}
if the utilityObject and delegate properties are both declared using retain, then self now retains self.utilityObject and self.utilityObject retains self.
See Why are Objective-C delegates usually given the property assign instead of retain? for more on this.
If you assign the delegate rather than retaining it then you don't need to worry about releasing it in dealloc.
It is usually indicative of bad design, since most delegates retain their objects (creating the potential for retain loops and thus leaks.) But there are some cases where an object should retain its delegate. These are usually cases where no reference is available to the object, so the delegate cannot be the one to retain it--but that itself can sometimes indicate bad design.
I've heard a lot of opinions on this as well. I don't know the Right Way, but I can tell you what I've arrived at through my own work.
You want to retain anything that you need to preserve your handle on. That's all ownership is, in a reference-counted environment. It's a declaration that "I'll need this later, don't let it go away on me".
That ALSO means you're responsible for releasing your claim on it. If you don't specifically do that, you're prone to various problems, but especially dealing with delegates which might well retain the object they're a delegate of. If you don't deal with your retention of the delegate, the ownership will be cyclical and the objects will leak. But don't forget to release what you retain, and you'll be okay.
Related
I am little confused about using Strong or Weak in my particular case.
I have one class ParentClass which has 3 object ContainerClass1, ContainerClass2 and ContainerClass3.
Each ContainerClass has its own strong properties with Mutable objects like NSMutableArray
Now in my case, I have to show only one ContainerClass at a time, so if ContainerClass1 is shown then ContainerClass2 and ContainerClass3 is not required.
So I thought when I show ContainerClass1, will set ContainerClass2 and ContainerClass3 objects to nil. Here I am confused whether just setting the other ContainerClass(not shown) to nil will release its memory? because they have strong properties to other objects.
Or should I need to set all other ContainerClass's strong properties to nil first and then set ContainerClass to nil?
Thanks in advance.
#zoeb, may this link will help you to keep away from basic memory problems.
how-to-overcome-memory-problems-in-iphone-applications-with-automatic-reference-counting
Edited:
As we know that Apple introduced ARC in IOS 5.0, ARC is compiler level feature that simplifies process of lifetime of objective-c objects. Before ARC introduced, We managed memory manually means “Manual Reference Counting(MRC)” . With MRC, Developer need to remember when to release or retain object. Means that Developer need to manage life cycle of objective-c objects.
According to Developer perspective, We are mostly interested to adding new features in our application rather then focusing on memory issues. But the things is sure that memory management perform crucial role in application success. To Provide help to Developer, Apple was figure out the way of automatically manage memory.
ARC is smartly manage memory but this is not 100 percent. We need to focus on some points while development to remove our application from lack of memory problem. Here i will try to provide solution of manage memory in ARC base application. that is not 100 percent as well. but its will try to help compiler to estimate life cycle of objective object.
Here are the some steps that you need to implement in your every controllers.
Step 1. Declare weak property to every UI Controls that used in application.
Example : #property (nonatomic, weak) IBOutlet UIButton* btnPost;
#property (nonatomic, weak) IBOutlet UITableView* tblMessages;
etc.
Step 2. As per our developer most confusing question is that whether compiler allow to declare “dealloc” method in ARC base application. the answer is yes but don’t allowed to declare “[super dealloc]” inside it. so override “dealloc” method in every controllers.
-(void)dealloc{
}
Step 3. Remove heavy loaded object from superview in “dealloc” method rather then setting just “nil” reference like MKMapview, ScrollView etc.
-(void)dealloc{
dictAddress = nil;
arrayList = nil;
[map removeFromSuperview];
[scrollView removeFromSuperview];
}
Step 4. Avoid dead lock mechanism. (Example : Class A and Class B is there. Class B is declared Delegate with property type “Strong”. so that Class A and Class B dependent on each other on one is going to release. so in that case “dealloc” method is not called of either classes. so that class keep in memory. to removed such cases we need to keep “Assign” reference to Delegate object.) this is just for example. We need to consider other things as well like “Keep weak reference for block so it will release objects once its execution completed”.
these are the basic steps that avoiding memory problems. Still if you face memory problems then you need to take help of Analyzer to find leak and memory usage.
Below link will help you to analyze memory.
Mamory analyzer
The confusion between strong and weak will be clear with the below link.
Differences between strong and weak in Objective-C
Can someone explain to me in detail when I must use each attribute: nonatomic, copy, strong, weak, and so on, for a declared property, and explain what each does? Some sort of example would be great also. I am using ARC.
Nonatomic
Nonatomic will not generate threadsafe routines thru #synthesize accessors. atomic will generate threadsafe accessors so atomic variables are threadsafe (can be accessed from multiple threads without botching of data)
Copy
copy is required when the object is mutable. Use this if you need the value of the object as it is at this moment, and you don't want that value to reflect any changes made by other owners of the object. You will need to release the object when you are finished with it because you are retaining the copy.
Assign
Assign is somewhat the opposite to copy. When calling the getter of an assign property, it returns a reference to the actual data. Typically you use this attribute when you have a property of primitive type (float, int, BOOL...)
Retain
retain is required when the attribute is a pointer to a reference counted object that was allocated on the heap. Allocation should look something like:
NSObject* obj = [[NSObject alloc] init]; // ref counted var
The setter generated by #synthesize will add a reference count to the object when it is copied so the underlying object is not autodestroyed if the original copy goes out of scope.
You will need to release the object when you are finished with it. #propertys using retain will increase the reference count and occupy memory in the autorelease pool.
Strong
strong is a replacement for the retain attribute, as part of Objective-C Automated Reference Counting (ARC). In non-ARC code it's just a synonym for retain.
This is a good website to learn about strong and weak for iOS 5.
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
Weak
weak is similar to strong except that it won't increase the reference count by 1. It does not become an owner of that object but just holds a reference to it. If the object's reference count drops to 0, even though you may still be pointing to it here, it will be deallocated from memory.
The above link contain both Good information regarding Weak and Strong.
nonatomic property means #synthesized methods are not going to be generated threadsafe -- but this is much faster than the atomic property since extra checks are eliminated.
strong is used with ARC and it basically helps you , by not having to worry about the retain count of an object. ARC automatically releases it for you when you are done with it.Using the keyword strong means that you own the object.
weak ownership means that you don't own it and it just keeps track of the object till the object it was assigned to stays , as soon as the second object is released it loses is value. For eg. obj.a=objectB; is used and a has weak property , than its value will only be valid till objectB remains in memory.
copy property is very well explained here
strong,weak,retain,copy,assign are mutually exclusive so you can't use them on one single object... read the "Declared Properties " section
hoping this helps you out a bit...
This link has the break down
http://clang.llvm.org/docs/AutomaticReferenceCounting.html#ownership.spelling.property
assign implies __unsafe_unretained ownership.
copy implies __strong ownership, as well as the usual behavior of copy
semantics on the setter.
retain implies __strong ownership.
strong implies __strong ownership.
unsafe_unretained implies __unsafe_unretained ownership.
weak implies __weak ownership.
Great answers!
One thing that I would like to clarify deeper is nonatomic/atomic.
The user should understand that this property - "atomicity" spreads only on the attribute's reference and not on it's contents.
I.e. atomic will guarantee the user atomicity for reading/setting the pointer and only the pointer to the attribute.
For example:
#interface MyClass: NSObject
#property (atomic, strong) NSDictionary *dict;
...
In this case it is guaranteed that the pointer to the dict will be read/set in the atomic manner by different threads.
BUT the dict itself (the dictionary dict pointing to) is still thread unsafe, i.e. all read/add operations to the dictionary are still thread unsafe.
If you need thread safe collection you either have bad architecture (more often) OR real requirement (more rare).
If it is "real requirement" - you should either find good&tested thread safe collection component OR be prepared for trials and tribulations writing your own one.
It latter case look at "lock-free", "wait-free" paradigms. Looks like rocket-science at a first glance, but could help you achieving fantastic performance in comparison to "usual locking".
Hi imagine I have properties in the .h file:
#property (nonatomic) NSString * myText;
#property (nonatomic) SomeClass * someObj;
Now, in the class implementation.
Say, I didn't forget to use synthesize, and I called:
#synthesize myText, someObj;
Now say in code I forget to put self before the property name (and directly refer to the ivar):
myText = #"Hello";
someObj = [[SomeClass alloc] init];
My question is: is this a problem? What problems can it result in? Or it is no big deal?
ps. Say I am using ARC.
My question is: is this a problem?
This is called "direct ivar access". In some cases, it's not a problem, but a necessity. Initializers, dealloc, and accessors (setters/getters) are where you should be accessing self's ivars directly. In almost every other case, you would favor the accessor.
Directly accessing ivars of instances other than self should be avoided. Easy problem here is that you may read or write at an invalid address (undefined behavior), much like a C struct. When a messaged object is nil, the implementation of that message is not executed.
What problems can it result in?
Biggest two:
You won't get KVO notifications for these changes
And you are typically bypassing the implementation which provides the correct semantics (that can be justified). Semantics in this case may equate to memory management, copying, synchronization, or other consequences of a change of state. If, say, a setter is overridden, then you are bypassing any subclass override of that setter, which may leave the object in an inconsistent state.
See also: Why would you use an ivar?
For clarity, I recommend always using
self.propertyname
as opposed to
propertyname
as this removed any confusion between what variable belong to the class or have been declared locally above in the method.
To enforce this, try to avoid using #synthesize at all, which is only needed if you provide both custom getter and setter (but not one or the other)
The compiler automatically allows you to use _propertyname in the getter/setter (which is necessary to prevent recursive calls of the function)
You should not access the underlying instance variables by accident, only if you plan to do so.
Unexpected side effects may be that KVO doesn't work, overriding accessor methods are not called and the copyand atomic attributes have no effect.
You don't need to use #synthesize since Xcode 4.4, if you use default synthesis the compiler does an equivalent of
#synthesize myText = _myText;
so that
_myText = #"Hello";
self->_myText = #"Hello";
are equivalent and myText = #"Hello"; results in an "undefined identifier" compiler error.
If you use just #synthesize myText the compiler does (for backward compatibility reasons):
#synthesize myText = myText;
which is error prone.
Note that there are valid reasons to use the underlying instance variables instead of the accessor - but it's bad style to do this by accident.
For 30 years now, the recommended practice has been:
use getter/setter methods or the new . operator to read and write ivars.
only access ivars directly when you must.
pick ivar names to prevent accidentally using them, unless the ivar is one that will always be accessed directly (that is why the default behaviour and convention is to prefix ivars with an underscore).
You need to access ivars directly in a few situations:
Manual memory management requires it. You won't need this if ARC is enabled.
If you are going to read the variable variable millions of times in quick succession, and you can't assign it to a temporary variable for some reason.
When you're working with low level C API, it probably needs a pointer to the ivar, Apples libxml2 sample code accesses ivars directly for example.
When you are writing the getter or setter method yourself, instead of using the default #synthesize implementation. I personally do this all the time.
Aside from these situations (and a few others), do not access ivars directly. And prefix all ivars with an underscore, to make sure you don't accidentally access them and to prevent them appearing in xcode's autocomplete/intellisense while you code.
The two main reasons for the convention are:
Getter/setter methods and properties can be kept around when the underlaying memory structure of your class changes. If you rename an ivar, all code that reads the ivar will break, so best to have zero code or almost no code that accesses ivars directly.
Subclasses can override getters and setters. They cannot override ivars. Some people think subclasses shouldn't be allowed to override getters and setters - these people are wrong. Being able to override things is the entire point of creating a subclass.
Fundamental features like KVC and KVO can fall apart if you access ivars directly.
Of course, you can do whatever you want. But the convention has been around for decades now and it works. There is no reason not to follow it.
Contrary to what other answers seem to agree upon, I would recommend to always use direct ivar access unless you are very clear about what you are doing.
My reasoning is simple:
With ARC, it's not even more complicated to use direct property access, just assign a
value to the ivar and ARC takes care of the memory management.
(And this is my main point:) Property accessors may have side-effects.
This is not only true for property accessors you write, but may also be true for
subclasses of the class you are implementing.
Now these accessors defined in subclasses may very well rely on state that the subclass
sets up in it's initializer, which has not executed at this point, so you calling those
accessors might lead to anything from undefined state of your object to your application
throwing exceptions and crashing.
Now, not every class may be designed to be subclassed, but I think it's better to just use one style everywhere instead of being inconsistent depending on the class you are currently writing.
On a side note: I would also recommend to prefix the name of every ivar with an _, as the compiler will do automatically for your properties when you don't #synthesize them.
I am pretty new to Objective-C and iOS-development, and I am currently trying to grasp how to do memory-management. My app in non-ARC btw.
This object is not declared anywhere in the code (not .h or anything) other than the line belove. Do I need to release/dealloc this object in any way to clear the space for it when I am done using it, or is this done automatically?
NSMutableURLRequest *restRequest = [[NSMutableURLRequest alloc] init];
The same goes for this one. Not sure if this is the same question, but here I don't use the words alloc & init before using it. Does that make any difference?
NSString *postLength = [NSString stringWithFormat:#"%d", [postData length]];
In this case, I am defining the object in the .h-file as well as retaining it. Does this mean that the variable will always be in memory (when initialized once obsly) unless I release/dealloc it? I guess if that is the case, that is something I should do in views when the view is unloaded?
#interface Storeage : NSObject {
NSString *deviceToken;
}
#property (nonatomic, retain) NSString *deviceToken;
In the .m-file I will alloc and use this object like in the first or second case (does not seems to make any difference).
Please bear with me if this question is stupid. I am used to low level Java-programming with GC.
Do I need to release/dealloc this object in any way to clear the space for it when I am done using it, or is this done automatically?
Since you are not using ARC, you need to manually send it a release message in order to dispose of its ownership. (Good piece of advice: don't think in terms of "freeing memory". Reference counting means that you increase and decrease reference counts, you get to own and cease to own objects, the deallocation of an object upon having lost all its references is done automatically. In other words, release does not necessarily mean deallocation.)
The same goes for this one. Not sure if this is the same question, but here I don't use the words alloc & init before using it. Does that make any difference?
It does. You only own objects that you create using alloc, new, copy, mutableCopy or reference using retain. You do neither one here, so you don't have to worry about releasing it either. (Technically, it's an autoreleased instance that will be returned, the run loop will take care of it.)
In the .m-file I will alloc and use this object like in the first or second case (does not seems to make any difference).
Make the difference between instance variables and properties. A property setter method, if declared as retain or strong, will retain (increase the reference count of) your object. But that's true only if you use the accessor method, and not when you access the instance variable directly. If you wrote this:
variable = [[SomeObject alloc] init];
then you need to release it just like you would do with any other (local) variable:
[variable release];
If you use the accessor method to set it:
self.variable = [[[SomeObject alloc] init] autorelease];
then you have to use autorelease when creating it (else it will have a reference count of 2 and you'll leak memory).
In both cases, you can also use self.variable = nil; to relinquish ownership. This only works for properties.
All this radically changes with the introduction of ARC, which I don't explain here for three reasons:
I'm not an ARC expert by any means;
I'd like to encourage you to learn MRC (which you seem to have the intention to) perfectly before trying ARC;
It was not the question.
When using ARC for iOS, is there any difference between the following?
#property (strong, nonatomic) NSObject *someProperty;
...
#synthesize someProperty;
//and then in the init method, either:
self.someProperty = aProperty;
//or
someProperty = aProperty;
I know that without ARC, self.someProperty is actually calling the synthesized setter method which sends a retain message to the object. But now with ARC, does it matter if I use dot notation for setting a property like this?
More generally, does ARC truly mean that I don't have to worry about reference counts at all? Or are there certain situations in which the way I wrote my code could cause ARC to make a mistake?
The difference is the same as in the case without ARC: by using dot notation, you are calling the synthesized setter, and by assigning directly to the ivar, you are going around the setter method.
Under ARC, there are no differences in memory management between the two options but you should still make a conscious decision between the two options: assigning directly to the ivar bypasses KVO, for example, while going through the setter method is slightly slower but probably safer in most cases, e.g. when you later decide to make the property atomic or override the setter.
Personally, I would always use the property notation self.abc = ...; except possibly in init where it is often desirable to bypass KVO. In short, use the same reasoning you used before ARC.