Clean iOS Architecture pt.4: Clean Memory Management in Swift with WeakRef

preview_player
Показать описание


We must be careful with `weak` properties as they can sometimes damage the design of our systems, especially when crossing module boundaries. In this video, we’d like to share with you a way to avoid retain cycles by using a `WeakRef` type, so there's no need to make your class properties `weak`.

`WeakRef` is a type-safe alternative to `weak` properties that maintains a clean cross-boundary separation of concerns. By using a `WeakRef`, we can leave the composition (and memory management) responsibility to the `Main` (or `Factory`/`Composer`) module.

★ Professional iOS Engineering S01

★ Download our new app

Connect with us on:

Рекомендации по теме
Комментарии
Автор

Very interesting approach, I’ve always be using the weak presenter and class type for the protocol

tiagofcp
Автор

Amazing, very clear. Thanks for this. Watching all your videos & I'm making sure to like all of them.

Revanish
Автор

New knowledge as always. It’s always interesting to see your videos. Thanks!

tityseptiani
Автор

Very nice video. Thank you for this. Do you have a video about Presenters?

jeraldo
Автор

Your code is incredibly clean! Is there somewhere I can look to for more examples?

ECEJamie
Автор

I don't think it's bad to always have delegates for protocols be weak reference types. I don't think it's bad to make the assumption that the delegate will be there and that the calling class doesn't need a strong reference to it. Because it is a convention that people generally know and understand. This WeakRef class type would need to be created for every protocol, and it just seems like it's unnecessary clutter and boilerplate code. I like the rest of your videos I've watched thus far though, and I purchased the Swift Feed App Case Study course because I need to learn all this architecture and iOS specific Design Pattern stuff and you were the first video series that actually went through them all in a decent amount of detail. I'm not sure if there are code examples for the MVP, MVVM, VIP, VIPER, and MVC iOS specific design patterns, but if there is I want to review it so I can be sure I'm connecting the concept on the diagram to what I know.

Just because the delegate property is weak I don't think creates a dependency in the wrong direction due to the conventions of delegates in iOS always being weak so you know if you conform to a protocol that you need something to keep you around independent of the protocol, by Apple's framework conventions.

Your swift examples are helping me learn proper Swift protocol oriented programming and Swift conventions in general though, thanks! I'm surprised at how much free content you provide vs paid. I really just bought the course because I wanted to reward you for your good content that I got thus far for free, but of course I will watch the paid content as well as the free content.

So guess I mean it's nice to have the main module be responsible for memory management as you say by making the implementer of protocols weak in the composition of all these components, but it defies convention and so I think may be too confusing to try and sell others on, at least in the beginning. Really I think the rule of always making delegate properties weak as an iOS convention is a safe one and well understood and practiced for implementing protocol callbacks.

doug
Автор

Thanks! Awesome tip! Can we call WeakRef some kind of Adapter pattern from GoF?

dennef
Автор

A Question: When we are in a view controller and use navigation controller to present another view crontroller, the 1st vc remains in the stack, right? So, its reference count doesn't drop to zero. So, it is not deallocated. What if I want to get the first vc deallocated (considering thay I am not keeping any back functionality from 2nd vc to 1st vc)? What do I have to do to destroy/finish the first vc? (sorry for using Android term, as I am graviating newly from Android to iOS)

souravdeb
Автор

a few years late on this comment. Anyways I'm wondering why is VC talking to UseCase. Shouldn't the presenter speaker to useCase? Wouldn't that avoid the cycle altogether?

reejosamuel
Автор

I have a doubt, Since AnyObject is specific for only class based objects, How will any Struct based WeatherDataPresenterOutput validates this. I tried Creating a Struct which confirms WeatherDataPresenterOutput protocol. But WeakRefBox initializer not accepting it.

protocol OutputProtocol {
func outputReturn(data: String)
}

class VC: OutputProtocol{
func outputReturn(data: String) {
print("Data is :\(data)")
}
}

class Presenter{
let output: OutputProtocol
init(output: OutputProtocol) {
self.output = output
}

func didFetch() {
output.outputReturn(data: "data")
}
}

class WeakRefBox: OutputProtocol {
weak var object: (AnyObject & OutputProtocol)?
init(object: (AnyObject & OutputProtocol) ){
self.object = object
}

func outputReturn(data: String) {
object?.outputReturn(data: data)
}
}

struct StructVC: OutputProtocol {
func outputReturn(data: String) {
print("strut data is:\(data)")
}
}

let vc = VC()
let st = StructVC()
let presenter1 = Presenter(output: WeakRefBox(object: vc)) //This works Fine
let presenter2 = Presenter(output: WeakRefBox(object: st))// Compile error:
error: argument type 'StructVC' expected to be an instance of a class or class-constrained type let presenter2 = Presenter(output: WeakRefBox(object: st))

MrSumittheking
Автор

Can you share a name of the graph app you are using?

belfort