> On Aug 30, 2017, at 6:45 PM, Yvo van Beek via swift-evolution > <swift-evolution@swift.org> wrote: > > When I'm writing code I like it to be free from any distractions that aren't > really relevant to the problem that I'm trying to solve. One of these > distractions is having to pay a lot of attention to retain cycles. As my code > grows, I start making extensions to simplify my code. > > I've created the following helper for DispatchQueues: > > extension DispatchQueue { > func async<T: AnyObject>(weak arg: T, execute: @escaping (T) -> Void) { > async { [weak arg] in > if let argRef = arg { execute(argRef) } > } > } > } > > It allows you to do this: > > DispatchQueue.main.async(weak: self) { me in > me.updateSomePartOfUI() > } >
Closures handed off to dispatch queues will not cause retain cycles. John. > When functions are passed as a closure, the compiler won't warn about a > possible retain cycle (there is no need to prefix with self). That's why I've > also created helpers for calling instance functions: > > func blockFor<Target: AnyObject>(_ target: Target, method: @escaping > (Target) -> () -> Void) -> () -> Void { > return { [weak target] in > if let targetRef = target { method(targetRef)() } > } > } > > func blockFor<Target: AnyObject, Args>(_ target: Target, method: @escaping > (Target) -> (Args) -> Void, args: Args) -> () -> Void { > return { [weak target] in > if let targetRef = target { method(targetRef)(args) } > } > } > > Calls look like this: > > class MyClass { > func start() { > performAction(completion: blockFor(self, method: MyClass.done)) > } > > func done() { > ... > } > } > > When you look at code samples online or when I'm reviewing code of colleagues > this seems a real issue. A lot of people probably aren't aware of the vast > amounts of memory that will never be released (until their apps start > crashing). I see people just adding self. to silence the complier :( > > I'm wondering what can be done to make this easier for developers. Maybe > introduce a 'guard' keyword for closures which skips the whole closure if the > instances aren't around anymore. Since guard is a new keyword in this context > it shouldn't break any code? > > DispatchQueue.main.async { [guard self] in > self.updateSomePartOfUI() > } > > I don't have any ideas yet for a better way to pass functions as closures. > > - Yvo > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution