Valentin Shergin Valentin Shergin - 7 months ago 25
Swift Question

Is there way to check a `unowned` (actually `unowned(safe)`) reference has been deinited?

Is there any way to check an

unowned(safe)
Swift reference for "availability"? So, I am looking for a hypothetical function like
isReferenceAccessible
in this example:

func someMethod() {
someAsyncOperation(parameters) { [unowned(safe) self] in
guard isReferenceAccessible(self) else {
return
}

self.someAnotherMethod()
}
}


Disclaimer: This question not about
weak
references!
I am aware of how
strong
,
unowned
and
weak
references work. And I don't want to use
weak
references (because it can be slow, and mutable). I know that
unowned(safe)
references still be allocated even if it is already
deinited
when we are trying to access it. And I know that a compiler can do this check and it actually check it before an application is crashed.

So, I believe it can be very powerful and well-performed technic/paradigm for breaking reference cycles in modern Swift.

Moreover, I believe it can be an awesome language feature! For instance, let's assume that we have the modifier called
shared_ownership
and it works thought above described behaviour like this:

method(parameters) { [shared_ownership self] in
self.someAnotherMethod()
}


... with implementation like this:

method(parameters) { [unowned(safe) self] in
guard isReferenceAccessible(self) else {
return
}

self.someAnotherMethod()
}


... with side effects (without
weak
-related complexity and perfomance penalty) equivalent to:

method(parameters) { [weak self] in
guard let strongSelf = self else {
return
}

strongSelf.someAnotherMethod()
}


Oh, it would be fantastic!

More info about the differences between
weak
,
unowned(safe)
, and
unowned(unsafe)
.

Update



I have found awesome Swift proposal that related the feature discussed above: Allow using optional binding to upgrade self from a weak to strong reference.

Answer

Suddenly I have found that my original base assumption that weak reference in Swift can be slow is wrong. As we can see from sources, Swift is actually using almost same implementation for weak and unowned references. So weak reference is almost as fast as unowned reference.

(But Objective-C is completely different story, it is using sidetable with tracking of all pointers to week references and deinit, deallocate, and zeroing as one step. And it can be slow.)

And because of this, my questions makes no sense. I have to use week reference and unwrap it as I proposed it in the last piece of code in my original question.

Update: Here is an awesome article by incredible Mike Ash that describes how weak and unowned references work under the hood in Swift.

Comments