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

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.

Related

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?)

Precondition Swift 3

I am following the last conference of Apple about the GCD on this link:https://developer.apple.com/videos/play/wwdc2016-720/?time=33
I got to the point where it speaks of the precondition here: https://developer.apple.com/videos/play/wwdc2016-720/?time=1267, a new feature in Swift 3.
Arrived at this point: https://developer.apple.com/videos/play/wwdc2016-720/?time=1474 is used this:
.register(observer:, queue:)
my question: how this function retains object BusyController?
https://developer.apple.com/videos/play/wwdc2016/720/?time=1550
You ask how this register(observer:queue:) retains BusyController.
First, let's step back: Let's not get lost in the details of his example. He's not saying that it will establish a strong reference, merely that it could, and therefore you should be cautious about just trying to clean up in deinit.
So, how could DataTransform retain BusyController? It simply could maintain a strong reference to its observer. Note, do not conflate this custom register method example with the standard observer methods: They're just saying "imagine that the DataTransform object established a strong reference to BusyController..."
But, as he goes on to say "but you're skilled developers, and you know how to fix this problem; use a weak reference." So, generally, we wouldn't write observation methods that maintained strong references to their observers.
But, as he goes on to say, even if you're good about avoiding strong reference cycles, the object graph can get pretty complicated, so it's not always a good idea to rely upon deinit to clean up. He's advocating for an explicit invalidate process, and possibly using preconditions to test that the object has been invalidated by the time deinit is called.

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

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.

Manually set nil to swift object to avoid retain cycle?

I've been profiling one of the apps written in swift lately and been very frustrated with ARC in general, coming from languages where mark-and-sweep GC is the norm.
Especially, UIViewControllers that are very complex with lots of dependencies to other class, I've been failing to get ARC working properly. But I know that simply setting retained objects to nil gets them deallocated without dabbling with ARC.
This is especially true for UIViewController where I can set nil to all retained objects in viewDidDisappear or the similar.
Is this kind of practice considered bad / harmful? Should I just try harder to get ARC working?
edit: By not working, I mostly mean to break Strong Reference Cycle, which becomes quite unwieldy when there are multiple hierarchies of dependencies.
edit: FYI, I'm aware that using weak / unowned in declaration / capture list breaks the retain cycle. I'm asking in cases where using those norms become unwieldy due to the complexity of an object or, rather, the retain cycle of an object.
I think you should take a look at your class structure - basically work out which classes should "own" certain properties (i.e. strong reference) and who just needs to be referencing them when they are available (i.e. weak references).
I think it is well worth thinking about this, as it will probably streamline your code. It will also give you an opportunity to really think about privilege - do all these other classes really need access to these objects etc.
The real problem with setting things to nil is that you have to be sure that you are catching all strong reference cycles and that, ultimately, you are not benefiting from ARC making your life easier.
Try deinit Method its wright way I guess
deinit{
person = nil
}

Objective-C weak reference zombie

I'm trying to create a zombie object to detect sending messages to a deallocated object.
Say i have a strong property object A with a weak reference to object B. When B is deallocated my weak reference becomes nil but calling a method e.g [obj1.obj2 somemethod] simply returns nil not causing a crash.
Is there a way to test zombies using weak references? I can only crash using unsafe_unretained.
Is there a way to test zombies using weak references
(I take it that by "zombies" you actually mean dangling pointers...)
Not directly, no. The whole point of ARC-weak references is that they prevent dangling pointers. (As you rightly say, they safely replace the potential dangling pointer with nil — and there's no penalty for sending a message to nil.)
The reason there can be dangling pointer crashes in real life is that most of Cocoa does not use ARC. (As you rightly say, it uses unsafe_unretained.)

Resources