At the moment it doesn't seem possible to define an unowned local variable in a guard statement or while loop. For example, I would like to be able to:
guard unowned let firstNode else {
return
}
or
while unowned let node = previousNode.next {
defer {
previousNode = node
}
...
}
Is there an elegant swifty way to do this? I'm working with large datasets and trying to avoid retain/release overhead.
Just to address this comment quickly, using unowned does not avoid retain/release overhead. Unowned references still contribute to a refcount. Consider this code:
final class Foo {
unowned let parent: Foo
init(parent: Foo) {
self.parent = parent
}
}
The caller performs a (strong) retain before passing it in. For typical properties, this saves some time in the init, but it means that unowned, weak, and non-stored ones add an extra release call.
Because init parameters are implicitly consuming they get passed in with a reference count of +1 so they need to be decremented/released at the end of the call. You can read more about it in the "borrowing and consuming parameter ownership modifiers" proposal.
Once that proposal extends to Copyable types you can get rid of the retain by marking the parameter as borrowing i.e. init(parent: borrowing Foo). In the meantime you can use the underscore __shared modifier which already generates code without swift_release today.
Coming back to the original question: I think this should be solved with this pitch: borrow and inout declaration keywords. This will allow you to write:
guard borrow let firstNode else {
return
}
This doesn't "copy" the value and therefore should not emit a retain/release pair IIRC.
while isn't called out explicitly in the proposal but I think its just an oversight. Feel free to ask in the pitch thread though.