Swift: Capture lists don't work with nested functions
| Originator: | kastansn | ||
| Number: | rdar://22700750 | Date Originated: | 2015/09/15 |
| Status: | Open | Resolved: | |
| Product: | Developer Tools | Product Version: | |
| Classification: | Other | Reproducible: | Always |
Summary:
Consider the following closure that would create a retain cycle if there wasn't used a capture list:
let object = SomeObject(callback: { [unowned self] in event
switch event {
.case SomeCase:
self?.doSomething()
.case SomeOtherCase:
self?.doSomethingOther()
}
}
This is all fine. [unowned self] prevents a retain cycle that would otherwise exist because self owns SomeObject and at the same time self is referenced within the SomeObject's callback closure.
Unfortunately, the capture list doesn't work anymore when referring to self within a nested function inside the closure as the following example shows:
let object = SomeObject(callback: { [unowned self] in event
func innerFunction() {
self.doSomething()
}
switch event {
.case SomeCase:
innerFunction()
.case SomeOtherCase:
self?.doSomethingOther()
}
}
The obvious fix here is of course to spare the nested innerFunction(). But sometimes, for matters of code clarity, it is nice to outsource parts of switch cases into local functions. This isn't possible here because, despite of using a capture list, self isn't unowned in the inner function's scope and therefore still creates a retain cycle.
Version:
Xcode Version 7.0 (7A218) / Swift 2
Notes:
@inline-ing the nested function doesn't work, either.
Comments
Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!