Why are there weak _and_ unowned? Why can we just not always use weak? - ios

I just read the ARC section in the Swift book and a few other related posts concerning weak and unowned references.
After my readings, I do have a clear understanding on what they are and in what situations each of them are to be used (see also this SO post which gives a great explanation of this).
However, I fail to understand why Apple even came up with these two solutions? Essentially, from a MM perspective, both come down to not creating a strong reference to the referred object (i.e. not increasing its retainCount). So, why even bother and provide two MM primitives here?
Now, developers need to understand when to use which of the two, and Apple did a great job in explaining the different scenarios, but they didn't say why. Wouldn't it have been simpler to e.g. only provide weak so that developers don't need to dig into the docs and understand the different use cases?
I guess, another way to phrase the question is, why at all should we use unowned, except for Apple telling us so? At least from a MM standpoint, this wouldn't make a difference and using weak where according to the docs we should use unowned wouldn't create a memory leak?!

The difference is in the optionality of variables. Like Apple says in the Unowned References section of the link you provided:
Unlike a weak reference, however, an unowned reference is assumed to
always have a value. Because of this, an unowned reference is always
defined as a nonoptional type.
The usage of this is more visible in a closure block. Here you do not have to use ? operator or get a reference on the object if you use it inside the closure.
Instead of writing this:
UIView.animateWithDuration(0.2) {
[weak self]
() -> Void in
self?.view.layoutIfNeeded()
}
However, if you can be sure that the reference to self will not be released before the animation and you can simply write unowned and do not have to use the ? operator or unwrap it with an if let statement:
UIView.animateWithDuration(0.2) {
[unowned self]
() -> Void in
self.view.layoutIfNeeded()
}

#Kádi's answer about weak variables being optional is correct, but incomplete.
Weak and unowned have a difference in meaning outside of Swift's Optional semantics. A weak reference is more accurately named an auto-zeroing weak reference. The system knows about an object stored in a weak variable, and when the object is deallocated, goes to the extra work to zero out the value. As a consequence of that, weak variables are optionals in Swift.
Unowned pointers are not memory managed at all. They are a raw memory pointer that can take any value. (They can still be typed to point to a particular type of structure, so they aren't always "raw" in the way a C void pointer is raw.) Unowned pointers are useful for pointing to malloc'ed memory, pointer arithmetic, and the like. Declaring a pointer type as unowned basically tells the compiler "Don't worry about it. I know what I'm doing." The burden is then on you to make sure the pointer is always valid, before you try to dereference it, and also manage the memory behind the pointer yourself.

Related

Create a Weak UnsafeMutableRawPointer

So I'm trying to use the CoreAudio method AUGraphAddRenderNotify(...) but I need a reference to the class that created this notification within the notification block. Because this is a C function, I can't simply add a [weak self] in closure capture. Looking at the Documentation, the last parameter of this method is allowed to be an UnsafeMutableRawPointer that will be passed in during the execution of the block as the first parameter. Following this suggestion, here is the code that I have:
let selfPointer = Unmanaged.passUnretained(self).toOpaque()
AUGraphAddRenderNotify(graph, { (audioPlayerPointer, _, _, _, _, _) -> OSStatus in
let audioPlayer = Unmanaged<AudioPlayer>.fromOpaque(audioPlayerPointer).takeUnretainedValue()
...
return noErr
}, selfPointer)
Here is my question:
I need to figure out how I can safely get the value behind this pointer (accounting for nil). More specifically, I want to safely access the audioPlayer and make sure that it hasn't been deallocated by the time I use it. Currently, everything works just fine until the audioPlayer gets deallocated and then my app crashes. I know that I can use AUGraphRemoveRenderNotify(...) to stop the notification before the object gets deallocated but unfortunately this method is not what I'm looking for. How can I check if the object that the pointer is pointing to has already been deallocated?
Thanks in advance!
Weak references don't really work like that
Interestingly, weak references don't actually point to the target object that they model. They point to side tables, whose lifetime is different from the target object.
A side-table entry is allocated when the first weak reference to an object is made.
The creation of every weak reference increments the ref count of the side-table entry, and every destruction of a weak reference decrements it.
Once the target object is deallocated, the side-table entry remains in place. That way, all the weak references don't become dangling pointers.
After eventual deallocation of the target object, all attempts to access a weak ref to the (now-dead) cause the weak-ref to be nil-ed out (which is what you observe as a user), but also deincrements the side-table entry
Thus, every weak reference either needs to be destroyed (e.g. goes out of scope) or attempted to be accessed before the side table entry expires.
Since these side table entries aren't exposed to "user land" Swift code, you can't make a raw pointer to them, and so you can't really deal with weak references in this way.
Alternate ideas
I have a few ideas of what you can do instead, though I haven't tried them.
You can exploit UnsafeMutableRawPointer pointer to pass in a Weak<T> wrapper, like:
struct Weak<T: AnyObject> {
wear var object: T?
}
Though I think it'll have to be a class, in this case.
or for some other mechanism, such as passing in a closure (which weakly captures the object)

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.

Swift - Capturing closures - Apple's swift programming guide snippet

In Apple's Swift programming guide, "Automatic Reference Counting" section, at "Resolving Strong Reference Cycles for Closures",
This snippet is mentioned:
lazy var someClosure: () -> String = {
[unowned self, weak delegate = self.delegate!] in
// closure body goes here
}
What is the point of the exclamation mark in the assignment "weak delegate = self.delegate!"?
I mean, why do you care if there is a value or not? In either ways, you will be receiving an optional delegate inside the closure body since delegate is declared weak, which must be optional, and you will have to access it as an optional.
On the other hand, if you know for sure there 'self.delegate' wont be nil when you access it, why not declaring it as unowned?
Therefore, why is the force unwrapping necessary here?
Can someone shed some light on this?
As there is not really any more context in the text around this example the only person who can know for sure is the author or maintainer of the Swift programming guide.
But here are some possible reasons that I can think of (in no particular order)
The author made a mistake (it happens)
It was required in an older version of Swift and the documentation has not been updated (keeping documentation up to date is hard)
The author wanted to make it obvious to others that creating the block if the delegate does not exist is a bug
The author wants to make it easier to track cases when a delegate was deallocated between creating the block and calling it (maybe for analytics purposes?)

Swift Memory management when pass a closure as parameter to singleton

I'm aware of the fact that closure can create retain cycles if it is assigned to a property of a class and instance properties of the class are used inside of the closure. But
1) what about the closure is not assigned to the class property but passed as parameter to a singleton's class method ?
2) How the memory is managed in this case ?
In a method of my controller (UIViewController) I have something like:
MySingleton.classMethod(parameters ..., completion: { () -> Void in
/**
doing stuff here
*/
})
If You are not assigning the closure to a property, but just passing it to a function You need to consider if the closure will be escaping or noescape. In Swift 3 by default all closures passed to functions are non-escaping.
Here is a little bit more info on the matter:
"noescape" - the passed closure is invoked before the return of the function
"escaping" - If a closure is passed as an argument to a function and it is invoked after the function returns, the closure is escaping.
Simple explanation : We need to mark closure as escaping when we pass it to a function and the closure will be called after this function returns.
General rule is when the closure is escaping You need to use capture list to prevent retain cycles.
Example
let closure = { [weak someVariable] (name: Type) -> Void in
....
// code
}
Additional info:
One weird thing is that optional closures are treated as escaping. And when we explicitly add escaping keyword, there is a compile error -escaping attribute only applies to function types.
See the below links for more info.
https://bugs.swift.org/browse/SR-2053
https://stackoverflow.com/a/39619298/5388473
https://stackoverflow.com/a/39846519/5388473
Update
The idea of using weak or unowned in the capture lists of escaping closures is that essentially We don't know what will happen with the passed escaping closure, it may be called sometime later from another function or it may be stored in some object, which may lead to a strong retain cycle.
weak vs unowned vs strong capture
For more detailed information check Apple ARC docs.
From Apple docs:
Swift provides two ways to resolve strong reference cycles when you
work with properties of class type: weak references and unowned
references.
Weak and unowned references enable one instance in a reference cycle
to refer to the other instance without keeping a strong hold on it.
The instances can then refer to each other without creating a strong
reference cycle.
Use a weak reference when the other instance has a shorter
lifetime—that is, when the other instance can be deallocated first.
Use an unowned reference when the other instance has the same lifetime
or a longer lifetime.
Keep in mind that the weak approach will add a boiler plate to the code and will be a little bit more slow, because ARC will add code for setting the weak variables to nil on their deallocation. It is a good practice to follow the rules stated above, when choosing weak or unowned.

When or should i even use the weak reference for an object of a class in swift?

As far as i know the weak reference of swift is used because if the object gets nil and you call a method from it, it won't crash your application and just gets ignored. But isn't it a bad practice to allow some of your code to call a function on a not existing object of a class? Wouldn't it be cleaner to just avoid this scenario with good code?
Example what i mean:
weak var manager: MyManager?
manager.someFunction()
Now if the manger object is nil it just won't get called. I know it has it's easy to write code like this but is it really the best practice?
Sorry if this questions was asked before, but i only found explanations of weak and strong. I ask this because a friend of mine told me to use the weak reference to avoid an error call and i think that this is not the best way to handle nil objects because it seems like dirty code to me.
You have been given some misguided information.
Weak is not about making safe calls, but avoiding strong cycles between object instances that will cause memory leaks.
Safe calls are done with optional chaining.
var manager: MyManager?
manager?.someFunction() // this will not raise error if manager is nil
manager!.someFunction() // this raise error if manager is nil
The main point is that using weak communicates something about ownership. It's also frequently used to prevent retain cycles.
That it nils out automatically is useful for some patterns like observing.
Calling methods on nil is a somewhat different topic, which often comes convenient and allows for cleaner (less cluttered, easier to read) code.
For doing more complex logic, you often assign the weak variable into a strong one, so that you can be sure that the whole code runs as you expect it to, and not suddenly works with nil in half the code.

Resources