[swift-evolution] [Draft] @selfsafe: a new way to avoid reference cycles

Brent Royal-Gordon brent at architechies.com
Sun Feb 19 02:15:15 CST 2017

> On Feb 18, 2017, at 5:24 PM, Matthew Johnson via swift-evolution <swift-evolution at swift.org> wrote:
> This proposal introduces the `@selfsafe` function argument attribute which together with a `withWeakSelf` property on values of function type.  Together these features enable library authors to create APIs can be statically verified to never extend the lifetime of the `self` a function they take may have captured.

Both of these mechanisms are weirdly ad hoc. They involve the callee assuming things about the caller that are not necessarily correct—in particular, that the caller's `self` is going to, directly or indirectly, hold a strong reference to the callee's `self`.

For instance, suppose you've read too many design pattern books, and you're using the Command Pattern:

	class DeleteRecordCommand: Command {
		let record: Record
		func execute(with viewController: RecordViewController) {
			let alert = UIAlertController(title: "Really delete?", preferredStyle: .alert)
			alert.addAction(UIAlertAction(title: "Delete", style: .destructive) { _ in
				viewController.performSegue(withIdentifier: "Cancel", sender: self)
			alert.addAction(UIAlertAction(title: "Cancel", style: .cancel))

Now, imagine that the `UIAlertAction` initializer used `@selfsafe`, hoping to prevent incorrect use of `self`. Well, that would be totally wrong in this case—it would weaken `self`, which *needs* to be strong, and leave `viewController` strong, when it's creating a retain cycle. `@selfsafe` didn't prevent a bug—it introduced another one, without any visible sign of it in the code.

*The problem is not `self`.* The problem is that you need to pay attention to memory management in Swift. And that's a tradeoff that's baked into the language.

Brent Royal-Gordon

More information about the swift-evolution mailing list