This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Weak and strong property setter attributes in Objective-C
I am new to iphone development . Can any one tell me when to use strong and when to use weak reference and also what is the difference between atomic and nonatomic. I went through many links but still I am not clear with it.
I also wanted to know the differnce between retain,copy and assign used prior to ios5.
Any help is appreciated..
Thanks,
Raj
When designing your data you need to understand the concept of ownership. Data owns downwards. Ownership can never go back up your data hierarchy. If A has a pointer to B, and B to C, then C owns A, you have a cyclic reference graph, which results in a memory leak due to A referencing C indirectly and C referencing A. Release A and it doesn't get deleted because C still has a reference, and it won't get deleted unless A does - a catch 22.
To avoid scenarios like this, you use strong pointers to point "down" your data, and use weak pointers for any back references (such as parent pointers for example).
If a property is atomic, it generates a setter that allows it to be set from multiple threads. You cannot have race conditions where one thread changes a property at the same time as another. Nonatomic properties don't have that thread locking system.
Finally, retain properties increase the reference count of an object when you assign them to it by calling [myObject retain] on the object. Copy calls [myObject copy] so the property does not refer to the original, but a copy and assign is just a straight assignment with no reference count adjustment.
Related
Update
To clarify, the access of the object during its deinitialization is not being done in its deinit method explicitly. The object in question has listers that get added to it (closures) and these closures are all executed within the deinit method. It is within these closures that accesses of the object is being performed with unowned references. And it is the replacement of those unowned references with unowned(unsafe) references that results in EXC_BAD_ACCESS' from no longer occuring.
It is these unowned(unsafe) references that I'm referring to when asking if they're safe to use if always executed during the object in question's deinit.
Original
I wrote a lot of code predicated on being able to clean up unowned references in the deinitializers of their unowned object. Lo and behold, that is not a feature of unowned references. But apparently it is of unowned(unsafe) references, at least that is the way it appears to be working right now — what once caused a crash accessing an unowned reference during its object's deinitialization, now is no longer crashing and is working as expected.
If guaranteed that all unowned references will not be accessed after deinitialization of their object, would it be safe to use it?
For more details, the aforementioned cleaning up entails removing the object from a set where the hashability is based off its contents' object identities. So if it's a plain unowned reference, when the set attempts to access its hash, it will crash if that procedure is being performed while the object is already deinitializing.
The reason the objects aren't removed from the set before they are deinitialized is because this code is a component of library that enables the addition of nodes to a directed acyclic graph. As a feature, I decided that I would not require consumers of the library to have to remove the nodes when they're done with them, they can simply add them to the graph, then when they're done, release their object (the node) as they would anyways, and because the library adds listeners onto the nodes to remove them from the graph in their deinitializers, it was anticipated that it wouldn't be a problem — that the graph would be able to be cleaned up transparently. Obviously it's a little more complicated now that it's apparent that unowned(safe) references can't be accessed while the object they're referencing is deinitializing.
If unowned(unsafe) works in the way it appears to, it would be a solution to this problem.
The only difference between unowned(safe) and unowend(unsafe) is that the save variant is implemented using proxy objects and it will reliably crash your app when you access it illegally.
The unsafe variant on the other hand is just a plain C-Style pointer which will sometimes "just work" (if by coincidence the memory has not been reused anyway) and sometimes will strangely crash or just report unpredicable results.
unowned is the same as unowned(safe)
Nevertheless, during deinit you may access all the propertys of your object, see The Documentation
And also:
I am not sure exactly what you have implemented but it looks like you are trying to duplicate the mechanism with tables Swift uses internally for keeping track of deallocations of weak references.
If guaranteed that all unowned references will not be accessed after
deinitialization of their object, would it be safe to use it?
Yes it would be safe. If you have this guarantee I think it would also be simpler to turn all your variables to implicitly unwrapped weak variables.
So if it's a plain unowned reference, when the set attempts to access
its hash, it will crash if that procedure is being performed while the
object is already deinitializing.
Obviously it's a little more complicated now that it's apparent that
unowned(safe) references can't be accessed while the object they're
referencing is deinitializing.
I do not think this is the reason for the crash, the memory is freed after deinitialization, during deinitialization you still have access to the instance to perform any manual cleanup you need, I would suggest to replace the complicated solution that keeps track of deallocated references, and simply rely on Swift to set to nil objects that are deallocated using weak references. If you do not want to refactor you code to handle optionals when make them explicitly unwrapped.
However if during deinitialization you access the object from an other reference(outside deinit) it will fail, this is to ensure consistency. See here that access an instance that is deinitialized will cause an app to crash.
This question already has answers here:
What is the difference between a weak reference and an unowned reference?
(7 answers)
Swift. Is the (absolutely) sole specific advantage of unowned over weak, performance?
(4 answers)
Closed 5 years ago.
I am working on Swift and I have little bit confusion on usage of unowned and weak keywords for memory management in Swift.
Can any one help me to understand where to use unowned ?
Thanks in advance!
The most important difference is that unowned variables are very dangerous in Swift.
weak is an optional type, unowned is NOT.
This means that you can create code that uses weak as part of the logic. (think of asynchronous actions that take place only if a view controller is still being shown on the screen, when the code is ran, if the reference is "weak" it will fail silently without causing any other issues if the code is written correctly)
On the other hand, when a variable is unowned you are basically saying that this variable will always refer to something. And unlike weak, if you call it and there's nothing it will crash.
You generally never wanna use unowned. (I haven't come across any case where I had to). On the other hand, "weak self" variables are quite common when writing blocks.
You can see a good explanation on this question:
Shall we always use [unowned self] inside closure in Swift
EDIT: Actually, check the first and second most voted answers. They provide a clear explanation on WHEN to use unowned and how it works. The second even has pictures!
As per apple docs
There are some pretty good examples given on the developer website, check this link
As far as blocks are concerned as per Apple Docs:
Define a capture in a closure as an unowned reference when the closure
and the instance it captures will always refer to each other, and will
always be deallocated at the same time.
Conversely, define a capture as a weak reference when the captured
reference may become nil at some point in the future. Weak references
are always of an optional type, and automatically become nil when the
instance they reference is deallocated. This enables you to check for
their existence within the closure’s body.
To conclude Use a weak reference whenever it is valid for that
reference to become nil at some point during its lifetime. Conversely,
use an unowned reference when you know that the reference will never
be nil once it has been set during initialization.”
I am building an app in Swift. I am creating my views in an entirely a programmatic way. In some instances, I have a ViewController that instantiates custom views. In addition, I may have variables like "var User" which gets populated after an Alamofire network call and is used in various UI elements throughout the view controller. Besides declaring delegates as weak var, are there any other rules that apply?
Also, is there a way for me to figure out whether I have a strong reference that should be a weak one? What should I be looking for?
The basic concept behind reference counting in Swift is one of ownership. Objects should hold strong references to any other objects that they "own", in the sense that they're responsible for the lifecycle of the other object, either alone or in conjunction with other objects.
A lot of object reference graphs in a typical application are hierarchical - one object owns a bunch of other objects, which each have their own children, etc. For example, a ViewController owns its window, the window owns its views, each view owns its subviews, and each subview owns the images, strings, or other content it displays. These are all strong references.
Weak references will typically be used for references that don't imply ownership. The delegate example is a good one - in most cases, a view does not own the delegate. The delegate object has a lifecycle independent of the view. In many cases, the delegate will be the same object that created/owns the view in the first place, for example a ViewController.
You do not want a strong reference that goes from a "child" to its "parent". That creates a circular reference, and both the child and the parent will hang around in memory until the application exits.
In addition to delegates and other "backwards-pointing" references, you will also see weak references used in caches, where you want to quickly return an object if it's requested a second time, but the cache shouldn't keep the object in memory if nobody's currently using it.
To properly answer your question, we would need considerably more detail, (please ...) added to your original question.
I would frankly caution you that "there are no rules" with regards to any issue as fundamentally "touchy" as weak references. Be especially careful not to "follow rules," imagining that thereby you will "be 'safe,'" when other aspects of your application's design do not clearly call for their use.
A "weak" reference is defined as a reference from one thing to another which, you assert, "is not sufficient to cause the referenced object to not be garbage-collected." If the memory-manager does decide to "reap" the object, it is supposed to set your "weak" references to NULL. It can do this at any time will do this at the most-inconvenient time.
One possibility worth contemplating in your application design is to use properties, backed by "getter" routines, instead of actual variables. Or, instead of storing a (weak ...) reference to something, put it into some sort of a "collection" and store its id. Yes, various forms of "getter routines" will be executed each-and-every time, but in the long run that might be more reliable than relying too-much on the memory manager. If you know that "all of the code, wherever situated," will have to pass through "this 'getter' routine," you can concentrate your bug-avoidance efforts at that one deliberate pinch-point.
I'm using ARC.
Sometimes I wrote the following code to assert a object should be deallocated:
__weak weakVariableOrProperty = someObject;
....
someObject = nil;
// or someObject = anotherObject;
....
if (weakVariableOrProperty) {
#throw [NSException exceptionWithName:NSInternalInconsistencyException reason:#"Object not deallocated" userInfo:nil];
}
For example, I use this code to check if a view controller is deallocated before creating a new view controller.
I believe that weak variable or weak property is set to nil immediately after last strong variable or property was set to nil or another object.
And this code is working as I expected until now.
Using weak variable or property to check if object is deallocated is a technique commonly used?
Is it possible that this code will cause problem in the future?
I believe that weak variable or weak property is set to nil immediately after last strong variable or property was set to nil or another object.
This is not exactly true, because an object could be autoreleased. In this case, the last strong reference may be gone, but the reference count of the instance would remain positive. In cases like that, the __weak reference would not be nil-ed out until the autorelease process takes place.
Is using weak variable or property to check if object is deallocated a technique commonly used?
I seriously doubt that this technique has gained much popularity, because ARC is a relatively new thing to Objective C. However, the technique appears valid.
Is it possible that this code will cause problem in the future?
This is very hard to guess, because the ARC Specification does not make any specific guarantees about the timing of nil-ing out the references, and because the spec allows compilers to optimize sequences of retain and release messages that they send to ARC objects.
Your explanation code will be prone to a race condition.
The object in weakVariableOrProperty could be released (since it's only referenced by a weak reference) after the if condition has been evaluated. To avoid this, introduce an ordinary variable, set it to weakVariableOrProperty and check it for nil instead.
That said, as #dasblinkenlight says, betting on exactly when an object will be gone is tough. In a reference-counted system you don't know what else is holding onto it. It may go away just after you've checked. You should be able to constrain your environment enough that you know the system's not squirreling things away, but both autorelease and weak references complicate things.
The best way to solve this is simply to have well-defined object lifetimes: view controllers that don't live forever, that you explicitly tell to go away and so on.
So I've tried using this technique to ensure that objects are always deallocated on a background thread. The [dealloc] for some of my classes was moderately heavy weight and could take a long time (10s of ms) which would freeze the main thread ever so slightly.
I decided to add all of these heavy objects to an array before they'd be released on the main thread, and then go through that array later on a backgroundd thread to remove them from the array. The thought was that the array would keep the retainCount alive until it could be removed from the array on the background thread, and then i could guarantee the cost of the [dealloc] wouldn't happen on the main thread.
To do this, i had the code below:
while([objectsToDealloc count] && /* other conditions to prevent infinite loop */){
__weak id ref = [objectsToDealloc lastObject];
[objectsToDealloc removeLastObject];
#synchronized(ref){
// synchronising on ref will retain it if possible.
// so if its still around,that means we didn't dealloc it
// like we were asked to.
// so insert it back into our array. once the object is deallocd
// it won't be able to be synchronized, because the weak ref will
// be nil
if(ref){
[objectsToDealloc insertObject:ref atIndex:0];
}
}
}
The idea was that if the array didn't contain the last reference (or if there were pending autoreleases on the object, etc), then the weak ref wouldn't nil out. I'd then #synchronize on the object - the synchronized block will retain + release whatever object is being synchronized - which would ensure the ref would stay alive during that block. if it was nil, then it'd been dealloced. if it wasn't nil, then i should add it back to the array and check back again later.
After testing with this code over the past few weeks, I cannot recommend this strategy to check for deallocated objects. I haven't tracked down exactly why yet, but very rarely the object will dealloc but the ref won't be nil yet, so i'll be adding an invalid object back into the array.
i've only caught this in the debugger one time, though i have crash logs of it happening a few times. You can see below that "nil" ends up in my array, even though the code above should protect against it.
Again, I suggest not using this technique for detecting when/if objects deallocate, and instead focus efforts on clarifying your object graph and relationships.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
#property and retain, assign, copy, nonatomic
Can someone provide me overview on the properties: retain, assign, copy, nonatomic.
I am the new in iPhone development and I don't know how and when to use these
Thanks in advance.
If you use your own getters/setters then these keywords don't have much of a meaning but if you use #property/#synthesize then u need to use the keywords.
Retain: In this case you get and extra object made that is the retain count for that object is increased by 1 for every retain and you need to release it if you are using arc.Retain is used when you don't want the value to be deallocated while it is set on the object.Also retain creates a strong reference,and an object cannot be deallocated until all of its strong references are released.
Copy: Copy is just reverse of retain as it just gives a copy of the object to work on and the actual value changed on copied object wont be reflected back on the real object . One should use a copy accessor when the setter parameter may be mutable but you can't have the internal state of a property changing without warning .
Assign:Assign is generally used for non-object Datatypes.
Non-atomic: Non-atomic offers thread-safety whereas default atomic doesn't but the read/writes of atomic are thread safe it uses an object level lock that ensure serialization of read/writes.Also ,the value returned from the getter or set via the setter is always fully retrieved or set regardless of what other threads are executing concurrently.If you specify strong, copy, or retain and do not specify nonatomic, then in a reference-counted environment, a synthesized get accessor for an object property uses a lock and retains and autoreleases the returned value.