I am starting with Objective-C development and trying to understand the weak and strong references. I think I understand it, but I am not sure about it...
Let consider that code:
#interface SomeClass {}
#property (nonatomic, weak) NSString* propertyName;
#end
Now, if I invoke somewhere in the code something like this:
NSString* s = someClassInstance.propertyName;
The reference counter is not incremented. Is my understanding correct?
Doubt 1: What is the reference counter value for propertyName?
Doubt 2: So... Could you give an example of when I can get the strong reference to this property? I hope you know what I mean or what I do not understand...
I will get the weak reference.
Declaring propertyName as a "weak" property means two things:
When you assign an object to propertyName, that object's reference count is not incremented.
When the object that propertyName points to is deallocated, propertyName will be set to nil.
Assigning the value of propertyName to another variable may or may not have any impact on the reference count. If you assign it to a strong property, you will almost certainly increase the refcount (since that is part of the semantics of a strong property). But ultimately the compiler will decide if modifying the reference count is necessary.
It's important to understand the concept of object ownership in Objective-C, whether you are using ARC or not, but the details of the actual reference count for a given object at any given moment are not so useful. Remember this: a strong property owns an object. A weak property does not.
First of all
"strong" is synonym of "retain" and "weak" is synonym for "assign" in ARC enabled application.
answer to Doubt 1:
Its retain count will be equal to the retain count of the object it is storing. as it is just a reference.
answer to Doubt 2
Answer to your doubts:
You should refer this link for understanding strong and weak type property
http://www.raywenderlich.com/5677/beginning-arc-in-ios-5-part-1
Related
As far as I know, when I dereference a dead weak reference in Objective-C, I get a nil value as the result. I'm wondering if there is any way to actually tell if there was a weak value assigned to the variable once it goes away as opposed to simply having a value of nil (for instance if the reference was never assigned).
Is there perhaps a lower-level runtime function that I can use?
I've taken to using a BOOL to record when the reference is assigned, but this feels ugly to me.
As Rob said, you can't do it directly. But you can do so indirectly.
By using associated objects, you can associate a subclass of NSObject with the object being weakly referenced. In that subclass, override dealloc to notify something that the weakly referenced object is being deallocated.
As long as you make absolutely sure that the weakly referenced object's associated reference to your NSObject subclass is the only strong reference to your subclass's instance, then you've effectively created a means of receiving a notification of when the weakly referenced object is deallocated.
Yes, it is fragile. One additional strong reference to that subclass's instances and the whole thing stops working.
No, there is no way to tell if a weak reference has been set to nil because its referent has been deallocated.
The weak reference is set to nil by weak_clear_no_lock in objc-weak.mm.
Class __weak *variable = preExistingObjectWithStrongReference;
If the above code is called, and a object with a strong reference is then pointed to by a new pointer 'variable', and the __weak attribute is assigned to it...
Does that simply mean that the reference count remains untouched? Or does it mean that the original object is now no longer strong referenced?
__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.
This means that you can use variable safely as long as there's any other strong reference to the same object. In a certain sense you can think of it as the 'reference count remains untouched' as you said.
Neither; this means that the compiler will keep the reference alive as long as someone else points to it strongly. If there are no more strong references, and all of the objects that refer to your weak pointer are gone, the object is deallocated. Generally you only use weak on objects that you do not own. If you do own them (i.e it is something that "belongs" the the class) then strong is a better choice. A weak is essentially an unretained property, except the when the object is deallocated the weak pointer is automatically set to nil.
I'm learning Objective-C and the Cocoa Framework (via Aaron Hillgass' book) and trying to figure out why the following line includes the "strong" identifier.
#property (strong) NSManagedObjectContext *managedObjectContext;
As I understand it, strong is the default so why do I need to explicitly declare it?
You can declare it without writing anything, But what happens when you come back to code or some other developer looks at your code?
You might have the knowledge that the default will be set to strong, but junior level programmer will get so confused to determine whether the declared variable is strong or weak.
Agree with Richard.
//Strong and Weak References
ARC introduces two new object reference qualifiers: strong and weak.
Under ARC, all object reference variables are strong by default.
And this doesn’t apply to just properties;
the default identifier with #property statement is assign for non-object types,
for object type should be strong.
all object references - property values, instance variables, automatic variables,
parameter variables, and static variables - act like a retain property under ARC.
In The Objective-C Programming Language:
assign
Specifies that the setter uses simple assignment. This
attribute is the default.
That is, the default attribute for the setter semantics is assign, rather than strong.
I am new to iOS development in general and have never dealt with manual reference counting (retain, release, autorelease). As such I don't have a good understanding of what magic ARC is performing.
I thought I understood until I was asked what type of ownership (weak, strong, assign, etc) should be given to a readonly property pointing at an object, such as:
#property (readonly,nonatomic) NSString* name;
I read here
Questions about a readonly #property in ARC that leaving off the strong/weak won't actually compile unless you specify a backing variable when you #synthesize the property; I just so happened to be specifying a backing ivar like this:
#synthesize name = _name;
Now I understand that the default 'lifetime qualifier' of a variable is strong, from here: http://developer.apple.com/library/ios/releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html#//apple_ref/doc/uid/TP40011226-CH1-SW4
So to cut a long story short - I am indirectly defining my property as (readonly,nonatomic,strong) as the _name ivar is implicitly declared as __strong.
I have a few questions:
Is strong the correct lifetime qualifier to use? I assume that it is, otherwise the object backing my NSString* wouldn't be owned anywhere and would thus be freed automatically (coming from Java land this makes sense as all references are strong by default).
Are there any other modifiers which make sense in this situation, such as copy or assign?
Does declaring the property as (readonly,nonatomic,strong) and (readonly,nonatomic) make any difference to the code which consumes the property? eg. does declaring it without the strong keyword cause the object pointer to be stored as __unsafe_unretained where the strong property would be stored in a __strong pointer?
Thanks!
EDIT
So as I understand now, the following applies to readonly properties:
For non-NSObject* types (int, float, void*, etc) use (readonly, assign).
For object pointers, use (readonly, strong) or (readonly, copy) - these function the same for readonly properties but you may want the copy semantics if you extend/subclass and redeclare the property as readwrite.
For object pointers, (readonly, weak) only makes sense if you are going to be storing an already weak pointer in that property (that pointer must be strong elsewhere or the object will be deallocated).
strong is correct to use if you want to keep a strong (owning) reference to whatever it is that you are pointing to. Usually, you do want strong, but in order to prevent circular references (particularly in parent/child relationships where if the parent points to the child and the child points to the parent, they will never be released) you sometimes need to use weak references. Also, if you want to keep a pointer to an object that you don't own but want it to be valid only as long as it exists, then you want to use a weak pointer because when it gets deallocated by the owner, your pointer will automatically get set to nil and won't be pointing to memory that it shouldn't be.
assign is used with scalar values, and is the default setter. copy makes sense if you want to automatically make a copy of the object and set your pointer to the copy instead of pointing to the original object. It only makes sense to do this if you have a specific need (usually because you don't want the object to mutate on you).
The link that you provided which shows that __strong is the default (and therefore you don't need to specify it) refers to variables and not to declared properties. The default for declared properties is assign so it certainly will make a difference. If you were wanting assign however, it makes no difference whether you specify it or not (other than just to be clear that it is what you wanted).
EDIT: However, as Jacques pointed out, this is changing with LLVM 3.1 and the default is changing from assign to strong. In this case, it makes absolutely no difference whether or not you specify strong and can leave it out if you want. Personally I think that it is good to spell it out (especially since there is a conflict between different versions) so that everyone looking at the code is on the same page. Others may disagree on this point though. :)
I would suggest reading the Declared Properties section of The Objective-C Programming Language here: <document removed by Apple with no direct replacement>.
One additional point: properties can get redeclared from readonly to readwrite. For example, a subclass may make a read-only property from the superclass read-write, similar to how many Cocoa classes have subclasses that add mutability. Likewise, a property may be publicly read-only but the class may redeclare it read-write for internal use in a class extension. So, when the class sets its own property it can take advantage of a synthesized setter that does memory management properly and emits appropriate Key-Value Observing change notifications.
As things currently stand, all of the other attributes of the property have to be consistent. It's conceivable that the compiler could relax this requirement. (Some consider it a bug.) Anyway, that's one reason to declare a readonly property with an ownership attribute like strong, copy, or weak – so that it will match the readwrite redeclaration elsewhere.
With regard to your question 3, are you asking if the ownership qualifier affects code which calls the getter? No, it doesn't.
These 2 lines of code work for me:
.h file:
#property (nonatomic, readonly, copy) NSString *username;
.m file:
#property (nonatomic, readwrite, copy) NSString *username;
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".