Omg I finally understand closures now! This was exactly the thing I needed. Gonna replace all my single function protocols with this
@Kilo_Loco5 жыл бұрын
hehe, glad I could open your eyes to closures. Just remember that delegates/protocols are a fine solution and this is a preference. A preference that I feel makes our code sexier that is 😉
@Nightsd015 жыл бұрын
Completely disagree. Protocols are a lot more powerful and flexible than just passing closures all over the place. And the memory management model for you typical delegate pattern is a lot simpler. For simple things like network requests a closure is fine. But for everything else a delegate greatly improves separation of concerns and you don’t have to worry as much about how a closure will implicitly capture references and possibly cause memory leaks. It gets even worse if you start using closures all over the place and start nesting them, makes your code much harder to read.
@Kilo_Loco5 жыл бұрын
Personal opinions are fine with me
@jonasekstrom24495 жыл бұрын
In this unnested example more readable and cleaner I think
@mr.erikchun58632 жыл бұрын
Don’t worry, he posted a video saying his wife is sucking kcoc
@jasonkendall36105 жыл бұрын
Been following you for a few years now man, always great content!
@jhogue273 жыл бұрын
OMG thank you for this example, I've been struggling to change from the delegate method to this!!
@Fullstackdesign5 жыл бұрын
I guess it also depends on the context of when you should and shouldn't use the delegator pattern. Using delegates creates a "tether" that helps abstract the details of the class you want to communicate to. Whereas in a closure you need a concrete representation of the class to access the information passed to the closure thus exposing all of the inner workings of said class. In summary, a delegate is great for abstracting the communication between two objects. I.E. object A should not know or care about object B. The communication is implicit/decoupled: A- - - - Delegate- - - -B In a closure, object A needs a concrete representation of object B. A---------B
@Fullstackdesign5 жыл бұрын
@David van Enckevort There was a miscommunication in my wording. Anyway, regarding your comment. Via a closure no, but if obj A has a reference of obj B then yes. One of the purposes of a delegate is to abstract the communication of objects and most delegates only expose the information that is needed.
@Fullstackdesign5 жыл бұрын
@David van Enckevort 👍
@Kilo_Loco5 жыл бұрын
Thanks for your input. I love the fact that we’re able to discuss these topics without being buttholes to each other. 😁
@gwapster135 жыл бұрын
Neat solution. This is pretty much how it works on web/javascript and I’ve always found it much simpler than Swift delegates.
@markuspfeifer84734 жыл бұрын
Exact same opinion here. I use closures even for forms: a form declares the data that can be passed in, and then you have a submit button. What I do there is to pass the current values in the form as arguments to a closure provided by whichever class created the form. Very handy pattern for UIKit where you don’t have bindings, still useful in SwiftUI where you can keep your stored data elsewhere but still need to know if the closure was called. I wonder if the planned multiple trailing closures help mitigate the need for delegates in more complex scenarios.
@fernandomontes50875 жыл бұрын
I knew there was a easier way of handling these situations than using delegates, but I didn't know how. Thank you for making this video, I will be implementing this in my projects!
@Kilo_Loco5 жыл бұрын
Glad I could add another tool to your tool belt. 😆
@TheFloydPinkus5 жыл бұрын
Another great video. I really enjoy watching your videos and I sure do learn a lot.
@milolajzelichowski69254 жыл бұрын
thx for good knowladge ! 2 days i spent for looking for about good way with use closure !:)
@CASMANWHAT5 жыл бұрын
Thx Kilo! U da mannnnn. I come from a JS background so i love this closure talk.
@Kilo_Loco5 жыл бұрын
Haha! That’s actually the part I’m working through understanding in JS right now. I think it’s time for you to make that video 😜
@donathmm38815 жыл бұрын
Wowwwww that's so awesome!!! So much better and less code!! How did you made the errors so pretty on 6:58 that looks different
@Kilo_Loco5 жыл бұрын
That’s the new look for errors in Xcode 10.2 beta. I’m using beta because it allows me to create these tutorials in swift 5
@Eugene.Berezin5 жыл бұрын
Very nice! I agree code is more DRY and clean with closures.
@domainxh5 жыл бұрын
Excellent video, I think you made a great point about delegate vs closure. For simple projects like this, I would definitely be leaning more towards closure. Though I think for both cases, you have to watch out for retain cycles, as that is the reason why you put down [weak self] inside of the closure, and likewise weak var for the delegate. Subscribed :)
@subinkk10004 жыл бұрын
Great one . Need to change my old codes 😀👍
@Kamrun4U4 жыл бұрын
Thank Kyle, like always, great content!
@Kilo_Loco4 жыл бұрын
Glad you enjoyed it!
@ravikirangajula60514 жыл бұрын
great video, great explanation but left with one question animalCell?.didTapNoise = { [weak self] animal in //some code } we are using weak reference here to avoid retain cycles but what will happen in below case animalCell?.didTapNoise = didTapNoise
@iosmayank4 жыл бұрын
I also prefer using closures over delegates majority of times :)
@arslankhan44805 жыл бұрын
wow Kyle i m first time watching your tutorial and honestly u r great bro 👍
@Kilo_Loco5 жыл бұрын
Thanks bro! Appreciate the support. Make sure you share the channel so it can help others
@karimahmed53934 жыл бұрын
What if ---- var didTapNoise:((Animal) -> Bool)? How could we send them in the button action ?
@david-tracy5 жыл бұрын
Dope... pretty cool to see the “Swift 5” videos making their way
@Kilo_Loco5 жыл бұрын
Yea, I like to be on the newest for the videos so people will be able to tell that the content is still relevant in the future
@david-tracy5 жыл бұрын
Right on
@david-tracy5 жыл бұрын
Kilo Loco I’m still working on that screencast based stuff with replaykit. I transferred it over to use the startCapture( ) method instead of startRecording( ) and working on setting it up to do a live broadcast. Working to keep my resume relevant.
@Kilo_Loco5 жыл бұрын
It’s always best to have a variety of apps in your portfolio. This shows that you have experience with a lot of different technologies and may even be close to the assignment you’re being interviewed for
@david-tracy5 жыл бұрын
@@Kilo_Loco You're not kiddin' I'm trying to find time to get back into concentrating on better architecture, design patterns & unit testing.. and then on setting up a CI pipeline. Simply haven't had the time - in the middle of interviews, that type of stuff Coming into the new architecture / MVVM and unit testing is really some next level stuff to pick up with fluidity. And Swift is just so vast in its own - a lot to learn there. And half the jobs maybe want you to know Objective-C.... Thank goodness I have some income from freelance work coming in. Exhausted brotha.. Stay up!
@VeryBlueBot4 жыл бұрын
Interesting. Im new to Swift and thought that delegate is the "Swift" way.. Using closures is basically callbacks like in any other language (with some synthetic sugar) Also, in React and React native (also in Angular in way) you can pass functions as properties to child nodes and then only trigger them from the child node (class) using only this patter things can get really ugly when there are a deep drill down you trying to pass My question is - how do you prevent "callback hell" with more complex code? Love your vids - very helpful and clear :) thanks
@mauricejulesm4 жыл бұрын
Thanks Kyle, this helped a lot!
@joet54485 жыл бұрын
Came to see if this had anything to do with protocols containing a single function (I too wondered how I could get around having to create a delegate just to utilize a single function).... BUT I stayed because of "poop". True Story. Subscribed.
@GG-hk5iz4 жыл бұрын
Thanks Kilo for great Video. And Nobody will kill you for not putting weak :P
@fleonardo58015 жыл бұрын
Clean and neat. Much appreciated, Kyle.
@Kilo_Loco5 жыл бұрын
Always a pleasure 😁 If there’s anyway to make my content better or if there’s a topic you want covered, please let me know.
@fleonardo58015 жыл бұрын
@@Kilo_Loco It would be great if you do a weekly segment tackling a Github repository and how it could be used in one's project
@joneikholm5 жыл бұрын
Nice that you try to improve conventional ways of coding. In this case though, one downside is that you create a new handler-object for each cell (line 32). So if there are 10 rows, you create 10 handler-objects. Compared to just one in the delegate pattern.
@Kilo_Loco5 жыл бұрын
Upside is that each handler object can have more dynamic code
@TheHacka20005 жыл бұрын
Brad Hesse said it the best, Delegates are extremely powerful compared to a closure and can provide a cleaner looking code base.
@BigCarso4 жыл бұрын
Callbacks can also provide a cleaner codebase like in this video. It depends what you're dealing with. Delegates can also be messy when you're forced to conform to functions you're not interested in.
@emillind66505 жыл бұрын
What about retain cycles when you are assigning the view controller function to the closure? Wouldn't that create a retain cycle? You are not defining self as weak anywhere.
@swipip4 жыл бұрын
Do you know a way to avoid the retain cycle in this situation ?
@x2web5 жыл бұрын
Hi, I really like your flow :) What is the best way to handle global User state, logged in status and so on? AppDelegate.user, shared class instance, or pass an object of class on every segue?
@Kilo_Loco5 жыл бұрын
The latter. Essentially you want to pass the user to every part of the app that you want to use it. Also you want to make sure you’re accessing the user from a class so that you are always working with the current user. If you use a struct, any changes that happen to the user on one screen wouldn’t apply everywhere else. You can accomplish what you want by having it stored in the App Delegate but this is generally considered bad practice because you would be pulling your user from the app delegate which is like pulling it from thin air.
@sandeepkumar66665 жыл бұрын
Ha ha.. Thanks dude.. It's helps me to get clear idea about closure usecases😘😘😘😘
@Kilo_Loco5 жыл бұрын
Always a pleasure 😘
@StewartLynch5 жыл бұрын
Two comments Kyle. First of all, your sample code is set for Swift 5 so that may confuse some people. I like using closures too, but your opening preamble is a little misleading. There is no need to use a protocol to implement the delegate. You can just use weak var animalCellDelegate: AnimalsViewController? in the AnimalCell class so then you can remove the didTapNoiseButton right up into the AnimalsViewController and remove the extension. You probably end up with about the same number of lines of code and in this case, I find the delegate pattern more readable.
@Kilo_Loco5 жыл бұрын
I don’t think i covered anything specific to swift 5 so this code should actually compile down to swift 3 I think. As for the example I gave, this was the most common and simplest example of where I could show the delegate pattern. There are a lot of other places this same ideology can be applied. I definitely wouldn’t have a delegate be of type AnimalViewController because then the cell is absolutely not reusable. Both delegates and closures solve this problem by being more dynamic. Sorry if you felt mislead, but I think I clarified any misunderstandings by the end of the video. Hopefully I expressed myself clearly enough for people to see closures as being a potential tool in their tool belts
@StewartLynch5 жыл бұрын
Don't get me wrong, I love your stuff. If I am not mistaken, the only reason you are using a protocol is to ensure that you have the delegate function in the AnimalCell. Isn't the protocol just a recipe? It really doesn't serve any functionality. Is what I am suggesting not the same thing without having to define the protocol. What if you used weak var animalCellDelegate: UIViewController? and then in the didTapNoiseButton function in AnimalCell you did this if let animalCellDelegate = animalCellDelegate as? AnimalsViewController { animalCellDelegate.didTapNoiseButton(for: unwrappedAnimal) } Does that not accomplish the same thing without having to define a protocol?
@Kilo_Loco5 жыл бұрын
The problem with that approach is that now your cell has to be updated every time another view controller plans on implementing it. Also, that view controller would have to have a function in it that the cell would know to call. The cell shouldn’t know about the object manipulating it, it should simply perform some set of tasks without having to check for specific “delegates”
@StewartLynch5 жыл бұрын
@@Kilo_Loco Fair enough. If you are going to be using that same cell with other viewcontrollers, I get it. If you are using the delegate pattern, then using a protocol in that case makes sense. For one offs though, there is no need to define a protocol. Having said all that, I am just rambling so please excuse me. I learn so much from watching your videos and appreciate all you do. Part of my learning technique is to ask questions about alternate approaches and in that way, I get a better understanding myself.
@Kilo_Loco5 жыл бұрын
Yea no problem, that’s what I’m here for. It’s also why I provide my content in a certain format. I try to come up with relatable situations that can help people see how they can implement the concept themselves and also be able to retain the knowledge
@MoPharaoh5 жыл бұрын
If I'm passing data from a root view controller to another view controller, is this something that should be done by a delegate? I'd have to get a reference to that root VC either by injecting self from the root VC to the second VC or just reference the navigation controller root VC. is this a good idea?
@Kilo_Loco5 жыл бұрын
Well if you’re passing data data from one vc to another, you should should be injecting data into that second vc. If you’re talking about sending data back from the second vc into the first vc, essentially you would change the line where you’re setting self as the delegate in the first vc , to a line setting either the functionality or the function to the closure property that you have set in the second vc
@SuperAbins5 жыл бұрын
hi nice job ..!! I have 1 doubt. Can I pass values from SecoundVC - FirstVC? which is a better way to pass data from SecoundVC to FirstVC
@Kilo_Loco5 жыл бұрын
Absolutely! You can think of the cell as being a second view controller and the original view controller being the first. It’s pretty much the same as using delegates
@SuperAbins5 жыл бұрын
@@Kilo_Loco yEa i did .. 😍 i got it.... its works. Thanks.
@guruitcompany5 жыл бұрын
Thank you! I love Swift👍
@Kilo_Loco5 жыл бұрын
Me too. I still think it’s the best language
@zinlinphyo80985 жыл бұрын
Thanks a lot. That's what I need for my single function protocol.
@Kilo_Loco5 жыл бұрын
Haha it just makes more sense, doesn’t it?
@edsergeev5 жыл бұрын
Doesn't assigning a function to a closure create retain cycle since we still use "strong self"? I guess we still need to use a closure with a single function called from "weak self".
@MaximGolovlev5 жыл бұрын
from my expirience it is creates cycles
@Kilo_Loco5 жыл бұрын
Yes, definitely can create a retain cycle depending on how the function is used
@stephenleemartinez5 жыл бұрын
Not necessarily. You could get a similarly clean look by creating a function or a computed property that returns the desired closure (weakly capturing self). If using a function though, you would have to call it in order to get the returned closure. I personally prefer the computed property. It’s a very common practice in RxSwift.
@Kilo_Loco5 жыл бұрын
Thanks for the tip 😁
@dawid.ramone5 жыл бұрын
nice one Kilo! Thx
@Kilo_Loco5 жыл бұрын
Thanks! It’s my please to provide the content 😁
@belafekete31255 жыл бұрын
Hi, Kyle It is great, video, swift is awesome. This video just right. Thanks
@Kilo_Loco5 жыл бұрын
Glad you liked it. If there’s anyway to make my content better or if there’s a topic you want covered, please let me know.
@aniltodkar61995 жыл бұрын
Thank You for this video
@MrJoeYellow5 жыл бұрын
Great! Is it right to say that completion handler follow the same logic?
@Kilo_Loco5 жыл бұрын
It’s an alternative to using delegates or notifications. They all kinda do the same thing, but there are times when you might want to use one over the other. That’s why I listed this as a Dev Preference in the thumbnail.
@MrJoeYellow5 жыл бұрын
Kilo Loco Thanks Kyle!
@Kilo_Loco5 жыл бұрын
My pleasure 😇
@nimasharifi34235 жыл бұрын
Hi kilo How do I can play songs in the folder of localhost?
@Kilo_Loco5 жыл бұрын
You would have to download the file like any other networking request. This would only work on your simulator since local host is local to your computer. As soon as you move to a real device, this no longer works
@nimasharifi34235 жыл бұрын
@@Kilo_Loco What shape?
@Kilo_Loco5 жыл бұрын
Square?
@nimasharifi34235 жыл бұрын
@@Kilo_Loco Please explain me with more details.
@Kilo_Loco5 жыл бұрын
You can’t access files from your computer on your phone. That’s what backends are for. There are servers that hold your information, in this case music files, and you would have to make an API call to your backend to retrieve the file.
@stefanvargas2745 жыл бұрын
Nice man!!
@Kilo_Loco5 жыл бұрын
Thanks! If there’s anyway to make my content better or if there’s a topic you want covered, please let me know.
@jimistephen5 жыл бұрын
Well, yeah, if you only have one function then a protocol is a little overkill. What if you have 15 functions and they may or may not need to be called?
@Kilo_Loco5 жыл бұрын
Then you could choose not to set those variables.
@dmitrykhrykin4 жыл бұрын
Nah, you're actually introducing a retain cycle when you pass an instance function as a callback - it acts as a closure with strong self capture.
@BigCarso3 жыл бұрын
Not necessarily
@zainahmed65023 жыл бұрын
just pass weak self inside capture list to fix that
@indiekidukАй бұрын
If it's a tap you can just use target/action you don't even need a closure or a delegate
@djk125875 жыл бұрын
FYI, your final example here is a retain cycle.
@Kilo_Loco5 жыл бұрын
Yes, in this case, it does create a retain cycle. My main point is showing that the syntax allows for this type of value setting
@christostsangaris47855 жыл бұрын
It surely misses the [weak self] argument of the closure. How would you introduce it in the final example?
@djk125875 жыл бұрын
Christos Tsangaris personally, for 1 to 1 communication between objects, I would use delegates, and make the delegate property weak.
@couches4 жыл бұрын
You forgot to click the lion button. We'll never know what sound a lion makes now
@applepie72825 жыл бұрын
my hero
@johnforde77355 жыл бұрын
If you have multiple functions that your delegate can call, then a delegate is a better. Otherwise, if you only have one function that it can call then a closure is simpler.
@Kilo_Loco5 жыл бұрын
Excellent recap
@adinolivier5 жыл бұрын
Thanks man :)
@Kilo_Loco5 жыл бұрын
My pleasure. If there’s anyway to make my content better or if there’s a topic you want covered, please let me know.
@wesleybritob5 жыл бұрын
Closure is ok if u do mvc but if u doing mvp u must use protocols.
@Kilo_Loco5 жыл бұрын
Just like any architecture pattern, its up to you to really choose which rules you follow and how you structure your code. But overall, yes closures can be used in MVP as well
@mrfran15 жыл бұрын
Hi could you talk about withExtendedLifetime(_:_:) Generic func?
@vietho25125 жыл бұрын
thanks
@Kilo_Loco5 жыл бұрын
Always a pleasure
@strzempa5 жыл бұрын
Maybe its fast but not really the best practise. Implementing the delegate is more safe and readable in this case
@Kilo_Loco5 жыл бұрын
Safety is about the same in both of these cases. Closures are actually more clear in this case when looking at the cell as an object. Best practice is debatable but closures work very well with SOLID principles
@strzempa5 жыл бұрын
@@Kilo_Loco I get your point of view but still its forcing yourself to use [weak self]. This approach is fine in this simple case but when the app gets bigger it may get coupled and less predictable compared to delegates
@Kilo_Loco5 жыл бұрын
Well actually you’re supposed to use a weak reference with delegates to prevent retain cycles as well. I feel that since using a capture list in almost every closure is common practice, I’m more likely to remember to use a capture list than to mark a property with weak, which I actually did in the video by accident and had to correct it
@strzempa5 жыл бұрын
@@Kilo_Loco I agree that both `[weak self] in` for closure and `weak var delegate` are pretty much equal. But remembering weak before delegate should be like riding a bike :)
@Kilo_Loco5 жыл бұрын
But capture lists are like sitting down
@vamsi38775 жыл бұрын
Thankyou
@Kilo_Loco5 жыл бұрын
My pleasure. If there’s anyway to make my content better or if there’s a topic you want covered, please let me know.
@soromiso3 жыл бұрын
cool, the code looks very sexy
@christostsangaris47854 жыл бұрын
Dude, i was the 666 like on this video! Damn! :)
@Kilo_Loco4 жыл бұрын
😈
@DanCojocaru20005 жыл бұрын
Now do that in Obj-C :P
@Kilo_Loco5 жыл бұрын
H/o let me go get my time machine 😛
@vpoltave5 жыл бұрын
Nice video. But i think there is no point of doing safe downcast UITableViewCell to AnimalCell. This is what i mean: stackoverflow.com/questions/42169147/force-downcast-when-programming-a-custom-uitableviewcell-in-swift
@Kilo_Loco5 жыл бұрын
You’re absolutely right. This should always work and force casting should be an okay thing to do right here. However, since I’m not passing the animalCell object as a value to anything, and simply accessing its methods and properties, there’s no real reason to force cast it either. This is another preference of mine and I like to stay on the safer side of things
@denisblack98975 жыл бұрын
Now get rid of storyboards and you are golden
@Kilo_Loco5 жыл бұрын
If you know how to do something in storyboards, it’s very easy to implement in code. However, that’s not the same for the other way around. My videos will continue to be done in storyboards because it’s faster to explain my point as well as limits the amount of confusion on the topic at hand