When I use
addObserver:forKeyPath:options:context:
In this method, will the observer be a strong reference or just a weak reference in ARC?
Any ideas for this problematic?
See the documentation here
Note: The key-value observing addObserver:forKeyPath:options:context:
method does not maintain strong references to the observing object,
the observed objects, or the context. You should ensure that you
maintain strong references to the observing, and observed, objects,
and the context as necessary.
In short: The method does not maintain a strong reference to the observer.
Related
This question occured to me while reading this.
My question is in reference to the image below:
Once john is set to nil, Person instance no longer has any more strong reference and hence will be deallocated. But Apartment has two strong references and one of which is by the property on Person instance that would be soon deallocated. I believe, this strong reference continue to remain after deallocation and goes out of reach by the code.
So, setting unit14A to nil will remove only one strong reference to Apartment instance and it should not be deallocated as there would be one more strong reference due to the above case.
But, as the document says Apartment instance promptly got deallocated. To me, this can only happen if at the time of Person instance deallocation it sets its apartment property to nil, by that removing that strong reference on Apartment instance. But I couldn't find any documentation to verify this.
So, How does the Apartment instance get deallocated? What happened to the strong reference from the Person instance apartment property?
Can someone help me to understand this?
Objective-C objects are reference counted, meaning that for each object, the system keeps track of how many other objects hold a reference to it. This is object's reference count. Two special messages, retain and release, are used to maintain the reference count behind the scene. Once reference count goes down to zero, the system deallocates the object.
ARC provides "magic" to make reference counting work in a declarative way. The compiler knows every strong reference in your code, so when you do this
myStrongRef = nil;
the compiler quietly inserts a call to release in front of the assignment:
[myStrongRef release];
myStrongRef = nil;
To me [deallocation of Apartment] can only happen if at the time of Person instance deallocation it sets its apartment property to nil, by that removing that strong reference on Apartment instance.
Setting a strong reference to nil one way of breaking a strong reference. It is sufficient, but it isn't necessary. The important thing about setting a strong reference to nil is not the act of setting itself, but what happens immediately before it: the instance referred to by the strong reference gets a release message, instructing it to decrement its reference count. That is precisely what ARC does behind the scene for you: it sends the release message to Apartment, without setting Person's reference to nil.
How does the Apartment instance get deallocated? What happened to the strong reference from the Person instance apartment property?
Once strong reference from Person has sent its release message to Apartment, that strong reference disappears. The actual pointer may be set to Apartment's address, but nobody cares about it, because the Person itself is unreachable.
The life of an object depends on it's reference count, not any actual pointer to the object.
Strong reference is a way of speaking, there is no difference between a strong and weak reference, they are just pointers. The difference is that when a strong reference is created the reference count of the object pointed to in incremented and when deleted the reference count is decreased. When an object's reference count would become zero the object is deallocated.
Your intuition is correct. When an object is being deallocated under ARC all the strong references it holds are first relinquished - essentially they are set to nil, but in practice the implementation may differ.
This is also what happens when a method returns, or a block of code containing declarations exits, all the strong references held in local variables are relinquished.
All the details can be found in the Clang documentation.
HTH
Obviously not before deallocation, but during deallocation.
When an object's reference count goes to zero, the deallocation process starts. The object is marked as "being deallocated". At that point, the object will die (unlike Java, where it can be recovered). If an object is marked like this, it cannot be assigned to weak references (they stay nil), or to strong references.
Then dealloc is called, that is the dealloc methods that you have written. After that, strong references are set to nil, reducing their reference counts, then associated objects are removed, and finally the memory for the object is deleted.
Hi every one whether some one will elaborate me that why it is recommended to use the _weak reference for delegates and not the strong reference? though we can also use the strong reference for delegates. Some one will please tell me with the better and descriptive example with simple way that in which situations should we use the strong reference and in which situations should we use the _weak reference for the delegates.
I went through one of the related question on stack overflow
Is it ever Ok to have a 'strong' reference for a delegate?
but it did not clear my concept properly.
Any help will be highly appreciated !!
Thanks.
Using __strong on delegate is very easy to create retain cycle:
say A has a strong reference to B, and some object set A as a delegate of B, if the delegate is strongly referenced, then, a retain cycle is formed.
Yes, It's east to creat a retain cycle while using __strong on delegate.
Addtionally, in ARC, we using weak on delegate,while the object using the delegate is released,the delegate will be nil automatically.
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".
I am new at objective-c.I have a question .I know little about Retain .All i know is Retaining an object creates a strong reference, and an object cannot be deallocated until all of its strong references are released. If two objects retain each other, neither object ever gets deallocated because the connection between them cannot be broken. In ARC we can not retain a object. But we can retain a property.
What is the difference between retaining a object and retaining a property.
Thank You
Happy coding.
After searching so many articles and links, I decided to put all the attributes information together:
atomic //default
nonatomic
strong=retain //default
weak
retain
assign //default
unsafe_unretained
copy
readonly
readwrite //default
Many thanks to all the people who give best answers here!!
a property is retain, mean the class own the property NSObject, that's nothing about ARC. ARC just do auto release reference count.
I have read the apple document about KVO, and it said:
Note: The key-value observing addObserver:forKeyPath:options:context:
method does not maintain strong references to the observing object,
the observed objects, or the context. You should ensure that you
maintain strong references to the observing, and observed, objects,
and the context as necessary.
The observer object not have a strong references to the observered object.
Does this man I can not call removeObserver:forKeyPath: in the dealloc method? Can it remove the observer automatically?
You must call -removeObserver:forKeyPath: manaully. iOS will not do it automatically.
Apple said does not maintain strong references to the observing object. I think it means, if you want to removeObserver for a temp var out off the temp var's scope, you should make the temp var as ivar, so you maintain the ivar's strong references.
If you do not call -removeObserver:forKeyPath:. You will make : 1) Something leak
such as you code like this :
[self addObserver:a forKeyPath:#"name" options:NSKeyValueObservingOptionNew context:nil];
if you do not call -removeObserver:forKeyPath:. It will console that :
An instance 0x756a1d0 of class MyClass was deallocated while key value observers were still registered with it. Observation info was
leaked, and may even become mistakenly attached to some other object.
Set a breakpoint on NSKVODeallocateBreak to stop here in the debugger.
Here's the current observation info:
[NSKeyValueObservationInfo 0x7574f60] (
[NSKeyValueObservance 0x7574f20: Observer: 0x7568280, Key path: pageCount, Options: [New: YES, Old: NO, Prior: NO] Context: 0x0,
Property: 0x7574fa0]
)
When you debug it, you will find : The self and the a are not leaking. The leaking thing is the NSKeyValueObservationInfo object
If you do not call -removeObserver:forKeyPath:. You will make : 2) Intermediate class never destroy && Infinity notification
As the Apple document about KVO says:
When an observer is registered for an attribute of an object the isa
pointer of the observed object is modified, pointing to an
intermediate class rather than at the true class.
When you removeObserver, if no observer is registered, the intermediate class will destroy. And If you not call removeObserver, the intermediate class will never destroy and when you change the property, the setter method of intermediate class will continue to send notifications.
removeObserver:forKeyPath: has nothing to do with memory management or maintaining references. It just tells the runtime that your object no longer needs to be informed of changes to the object at that keyPath.
No, you must call -removerObserver:forKeyPath: when it is no longer needed, else the KVO system will have some dangling pointers that may leak or become attached to another object that doesn't expect it.
no, you have to call it.
not strong is NOT always weak
but in this case it means unsafe_unretained.
If you don't remove the observer you get an error message: "the object XY was deallocated while there was still a observer"
AND it might crash