I'm new to objective c and I've got an interesting situation where I need two different NSDictionary objects that point to the same values. In that situation should I use strong or weak in the property declaration? Or should I do strong in one and weak in the other?
In Game.m
#property (strong/weak, nonatomic) NSDictionary* answers1;
In User.m
#property(strong/weak, nonatomic) NSDictionary* answers2;
In both cases the key will be an integer, but the value will be an answer object of my own making. Both answers1 and answers2 will need to exists for roughly the same amount of time. When it comes time to get rid of one it'll be okay to get rid of the other.
Both should probably be strong. Each class should do its own memory management without having to worry about what other classes are doing. Therefore, each should keep its own strong reference.
In this case, the best would actually be copy. This way, in addition to retaining the dictionary, you will create an immutable copy of the one passed to you, ensuring the dictionary does not get modified from an outside influence (for example, passing a mutable dictionary which can later mutate).
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".
As a new iOS programmer, I've had a slew of bugs to fix today, a few of them have been related to me using weak properties instead of strong.
I realise that a good programmer wouldn't have this problem and would only set the properties to strong that need to be, but nonetheless, in my newbie eyes, I can't see why I should use weak, it only adds the risk of problems.
In general, you should decide between weak, strong, assign, and copy by looking at the relationship between the class holding the property and the value of that property, and also the kind of the property being passed.
If the property being set is primitive, use assign (or do not use ownership qualifier at all)
If the property being set is a scalar, immutable object, use strong
If the property being set is a scalar, mutable object implementing NSCopying protocol, use copy
If the property being set is mutable, and the ownership is transferred to your object, use strong
If the property being set is a mutable object implementing NSCopying protocol, but the ownership remains with the caller, use copy
If the property being set is a back reference (i.e. a "to parent" property in a "child" object), use weak.
The concept of ownership is very important in reference counted memory models. This is the primary driving factor behind your decision. You need to decide where is the primary owner of an object, and give that owner a strong reference. If an ownership is shared among a group of objects, give them all a strong reference.
The most difficult situation is when objects could own each other, directly or indirectly. In this case you would be better off replacing "ownership" with "knows about", give all objects a common "top" owner who "owns" everybody, and model the "knows about" relationships with weak references.
weak and strong are very important to get right for memory management purposes.
strong will increase the reference counter for the pointer, and you effectively say that you own the object.
weak does not increase the reference counter, and the object can potentially disappear at any time. If you have a cyclic dependency, you should use weak to avoid a memory leak (two objects both having a strong reference to each other is a cyclic dependency and those objects will never be released).
You should always think about your memory management, but a good rule of thumb is that the property should always be strong, unless you positively know that it is retained elsewhere. Multiple objects can have a strong reference to the same object with no problems, as long as no cyclic references occur.
Some super basic rules of thumb:
If you want the object to stick around at least until you are finished with it, go with strong
If you can handle the object disappearing without it hurting you too bad (i.e it is the parent that created you that might be nice to know about but not super important) then use weak
if it is not an NSObject (so is an int, bool float or other primitive type) use assign.
A rule of thumb that I use is: if the object is retained somewhere else, use weak. The biggest thing for me is when using interface builder. If you have an IBOutlet, you can make it weak, because that object is taken care of in interface builder and in the XIB file
#interface PaneBean : NSObject
#property(nonatomic,copy) NSString *name;
#property(nonatomic,copy) NSString *type;
#property(nonatomic,assign) NSInteger width;
#end
I have a PaneBean as is shown above.
Whether I should use #property(nonatomic,copy) or #property(nonatomic,strong) for my (NSString *) name? What is the difference between them?
And is it right to write 'assign' for NSInteger?
Any help appreciated.Thanks in advance!
'copy' will cause the setter for that property to create a copy of the object, and is otherwise identical to strong. You would use this to make sure that if someone sets your property to a mutable string, then mutates the string, you still have the original value. If the string isn't mutable, Cocoa will silently optimize out the copy operation, which is nice :)
'strong' will keep the property's value alive until it's set to something else. If you want incoming mutable strings to change out from under you (not impossible, but not all that common, a thing to want), then strong would be the right thing to do. Generally strong is more useful for objects that represent something more complex than a simple "value" (i.e. not NSString, NSNumber, NSValue, etc...).
'assign' is the default (and indeed only) possible setting for an integer. Integers can't be retained or copied like objects.
For attributes whose type is an immutable value class that conforms to the NSCopying protocol, you almost always should specify copy in your #property declaration. Specifying retain is something you almost never want in such a situation.In non ARC strong will work like retain
Here's why you want to do that:
NSMutableString *someName = [NSMutableString stringWithString:#"Chris"];
Person *p = [[[Person alloc] init] autorelease];
p.name = someName;
[someName setString:#"Debajit"];
The current value of the Person.name property will be different depending on whether the property is declared retain or copy — it will be #"Debajit" if the property is marked retain, but #"Chris" if the property is marked copy.
Since in almost all cases you want to prevent mutating an object's attributes behind its back, you should mark the properties representing them copy. (And if you write the setter yourself instead of using #synthesize you should remember to actually use copy instead of retain in it.)
copy sends the copy message the object you set, while strong only retains it (increments the reference count).
For NSString , or in general any inmutable class with known mutable subclasses(NSArray, NSDictionaty, NSSet), copy is preffered to avoid clients setting a mutable instance and modifying it out of the object.
For primitive types(int for example) copy/strong does not make sense and by default assign is used. Is up to you if you want to put it explicitly or not.
Strong indicates composition, while Weak indicates aggregation.
Copy means that a new object is to be created before the contents of the old object are copied into the new object. The owning object, PaneBean in this case, will be composed of the newly created object.
I have a pool of objects I keep inside an NSMutableArray so if any other objects want to reference them instead of creating new objects I will simply give it a reference to an object I have already created.
In the past I would monitor retain/release calls on these objects, and when they reached a retain count of 1 (my array only) I would remove them from the array. However I am struggling to do this with ARC because it doesn't let me monitor retain/release, how would I go about doing this?
Creating a way to manage objects based on release/retains calls, it's dangerous. If Apple happens to change the way it works, you are screwed. And apparently, that's what happened, when you start using ARC. There are two things:
1) You want to keep the objects inside the NSMutableArray independently if they are being use by other objects or not. In that case, just create a __weak reference to that objects, and in that way your object, that is inside the NSMutableArray, is kept alive.
2) Once there are not references to the object, just remove it from the NSMutableArray. Add to the NSMutableArray a __weak object. Once the strong one is release, the one inside the array will be as well, although I don't really like this approach as I find it dangerous. If you go for this option, use this to store the objects:
NSValue *weakObject = [NSValue valueWithNonretainedObject:anObject];
[array addObject:weakObject];
In the end, you can simply remove ARC from that specific file, and you can keep the monitoring.
I wouldn't bother with such a complex system. Just work with strong and weak properties and don't try to second guess performance. You are trying to build a memory management system yourself which makes little sense with ARC around. Creating and deleting objects is generally a tiny percentage of performance of any objective-c app; after years of using Instruments to monitor performance I don't worry about this part any more.
First, you should write simple code, intended for humans.
Do not worry about such performance issues until you have proven (via instruments or some other measure) that this is a critical bottleneck.
That said, creating certain objects can be really expensive, so keeping a cache for certain objects is not in and of itself a bad idea. However, you should never rely on reference counts, even in non-ARC code. Apple docs are very clear about this.
The alternative, as Jacky pointed out is a weak reference. Unfortunately, you can not put a weak reference into standard collections (though, ironically, you can put them in C++ collections and they will be managed correctly).
However, you can create a simple wrapper class to hold a weak reference.
#interface WeakWrapper : NSObject
#property (readonly) id object;
- (id)initWithObject:(id)object;
#end
#implementation WeakWrapper {
__weak id _object;
}
- (id)object {
return _object;
}
- (id)initWithObject:(id)object {
if (self = [super init]) {
_object = object;
}
return self;
}
#end
You can then place these objects inside collections, and then...
WeakWrapper *wrapper = // get the object from the collection
id object = wrapper.object;
if (nil == object) {
// You know the object that was being referenced no longer exists
// so this wrapper can be removed from the collection and destroyed.
}