assign in NON-ARC and retain cycle - ios

How retain cycle was tackled in NON-ARC !
I know assign is an alternative to weak.
weak will have its value set to nil If object allocated is deallocated whereas assign is not
so how it was done earlier can anybody help me understand

Zeroing weak references (what ARC calls weak) only exist under ARC.
Non-zeroing weak references (what ARC calls unsafe_unretained) can be used in MRC or ARC, and is the only kind of "weak reference" that is used in MRC.
You are asking how to avoid dangling references with non-zeroing weak references. You just have to design the logic of the program so that it doesn't happen. It's not that hard.
Usually, a "parent" object will have strong references to "child" objects, and then a back-reference from the "child" object to the "parent" will be a weak reference (in this case a non-zeroing weak reference). All you have to do is, when the "parent" object is deallocated, in its deinitializer, nil out the back-references that the "child" objects have to it -- it can access these "child" objects since it has a reference to them.

Related

Why Reference Counters All Start with +1?

As per swift/stdlib/public/SwiftShims/RefCount.h:
- The strong RC is stored as an extra count: when the physical field is 0 the logical value is 1.
- The unowned RC also has an extra +1 on behalf of the strong references
- The weak RC also has an extra +1 on behalf of the unowned references
I'm wondering why an object initialises with +1 to all counters, what's the point of making extras?
The unowned count is stored in the object's directly-allocated storage. When an unowned reference is destroyed, the runtime decrements the unowned count. If the decremented count is still above zero, the runtime knows that there is still at least one strong or unowned reference to the object, so the runtime knows it should not deallocate the object's storage. (The storage remains allocated until all strong and unowned references to the object are destroyed.) So, when the runtime destroys an unowned reference, it doesn't have to check the strong count to know whether to deallocate the storage. This saves time in the case where all unowned references are destroyed before the last strong reference is destroyed.
The weak count is stored in the object's “side table” entry, which isn't allocated until it's needed (which is usually when the first weak reference to the object is created). When a weak reference is destroyed, the runtime decrements the weak count. If the decremented count is still above zero, the runtime knows that there is still at least one strong or unowned or weak reference to the object, so the runtime knows it should not deallocate the side table entry for the object. (The side table entry remains allocated until all strong, unowned, and weak references to the object are destroyed.) So, when the runtime destroys a weak reference, it doesn't have to check the unowned count (or the strong count) to know whether to deallocate the side table entry. This saves time in the case where all weak references are destroyed before the last unowned (or strong) reference is destroyed.

Is it redundant in Swift to use weak and optional for the same variable?

I'm new in Swift and in the Apple docs I see:
Use a weak reference whenever it is valid for that reference to become >nil at some point during its lifetime.
Shouldn't I achieve that just by using "?" for optional types?
in other words:
Do the weak and ? overlap?
The compiler complains if I don't define a variable as optional when is weak, so I feel like I could just remove it and forget about it, but I feel I'm just misunderstanding it.
Thanks!
No, weak and optional are not the same, but there is some interplay between the two.
Optional just means that a variable can be nil, either by assigning nil yourself, or becoming nil through some other means.
The weak keyword has to do with memory management. When a variable is not weak (i.e. it is strong), it means that ARC holds a strong reference to the instance that is assigned. So even when there are no other references to it, the instance will stay alive in memory because the variable still "holds it".
When a a variable is weak, it does not hold a strong reference to it. That means that when there are no other strong references to it, the instance will be deallocated, and the variable will become nil automatically. This also explains why a weak variable must be optional.
The document that you linked to actually explains this quite clearly.
weak is related to memory management that ARC should remove that variable from memory or not. If your variable is weak then ARC would clear that memory to which it is pointing to as soon as all the strong references to that memory destroyed and when the memory is cleared then even the varaible is non-optional it will have nill because its memory is cleared.
But the optional has nothing to do with memory and it is directly related to the variable value that it can either contains the actual value or the nil.
Optional and non-optional properties differ in that optionals may be nil, while non-optional cannot.
weak and strong (property is strong by default without weak keyword) properties differ in that weak don't increase property's retain count, while strong do. If a weak property isn't strongly retained somewhere else, it will be deallocated. weak properties must also be optional.

Doubly linked list in Swift: why is only one of the references declared weak?

class DoublyLLNode<T>{
var value<T>?
weak var prev: DoublyLLNode? = nil
var next: DoublyLLNode? = nil
}
Why is one value, either prev or next, marked weak? Can't we make both as weak? If yes, why? If no explain.
If both are weak there won't be any strong references to any of the nodes and all of the nodes will be deallocated.
When there is a parent/child relationship you typically have a strong reference to a child in the parent and the child has a weak reference to its parent. Think of next as the "child" and prev as the "parent".
If both are strong you end up with reference cycles.
When you have a weak reference to an object, that object can be deallocated at any time, including while you still hold the weak reference to it. When you have a strong reference to an object, that object will not be deallocated until the strong reference goes away.
Thus, if all of your items in a linked list only have weak references to each other, they can all be deallocated while you're using them since there is no strong reference to any of the items.
You also can't make both references strong. You will create something called a strong reference cycle. This is when two objects refer to each other with strong references. Thus, it is impossible for either of the two objects to ever be deallocated (since they reference each other) and you waste memory.
In a linked list node, you want one of the references (either the next or the prev reference) to be strong. Then every object in the linked list will have a strong reference. If the next reference is strong, then for any node x, node x - 1 will have a strong reference to it (and presumably whatever code is using the linked list will have a strong reference to the head). If the prev pointer is strong, then for any node x, node x + 1 will have a strong reference to it (and you'll need to somehow make sure that there is a strong reference to the tail... otherwise, the tail will be deallocated, then the node in front of the tail, and on and on until all nodes are gone).

Are Unowned references set to 'nil' when deinitialized?

I'm confused on this topic in swift where it is said that unowned references must always have a value and cannot be optional, also meaning they cannot be set to 'nil'....well I just saw a program on the Apple documents for swift that instance 'A' with an unowned reference to instance 'B' was deinitialized and deallocated right after instance 'B' was deinitialized/deallocated......when a var is deinitialzed/dealloc doesn't it mean they are set to 'nil'??? Instance B is an optional so sure it can hold 'nil' but why did instance 'A' get deinitialized when its supposed to always have a value????
PS: If this helps..... instance 'B' was an optional type with a strong reference to instance 'A'
The point of an unowned reference is to hold a weak reference to something that you are guaranteeing (based on your application logic) will not be deallocated prior to the object that has the unowned reference. You can read more in the documentation.
In a sense it is a similar thing to an implicitly unwrapped optional type (such as String!). You're telling the compiler that you won't ever access the value when it is nil, and if you do your program will crash.
An object is deinitialized when its strong reference count drops to 0, but it is not deallocated until its weak reference count also drops to zero.
"Deinitializing" an object means that its deinit function is executed if it has one, releasing any resource that it holds, and clearing any references that it may have (potentially deinitializing and deallocating more objects). "Deallocating" is when the memory is reclaimed by the runtime. A deinitialized object's reference counting header is still valid.
When you access a weak reference, the Swift runtime ensures that the object is still in an initialized state. If it isn't, the weak reference is set to nil and the deinitialized object's weak reference count is decremented.
Unowned references also count towards the weak reference count. When you access an unowned reference, the Swift runtime also ensures that the object is in an initialized state; but if it is not, instead of clearing the reference (it can't do that because it is not optional), it crashes your program.
This effectively makes an unowned reference behave like an implicitly-unwrapped optional, whereas a weak reference behaves like an optional.
The tradeoff for self-zeroing weak references and clean-crashing unowned references is that an object's backing memory cannot be reclaimed until all of its weak references have been tested or deinitialized, and until all of its unowned references have been deinitialized.
Source: Swift runtime code
It is meaningless to talk about what an unowned variable "holds" after the object it points to has been deallocated, because Swift guarantees that your app will crash if you ever try to access the variable after the object it points to has been deallocated:
Note also that Swift guarantees your app will crash if you try to
access an unowned reference after the instance it references is
deallocated. You will never encounter unexpected behavior in this
situation. Your app will always crash reliably, although you should,
of course, prevent it from doing so.

Retaining property in arc

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.

Resources