Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 891
Valentin Shergin Avatar asked Jan 17 '16 20:01

Valentin Shergin


1 Answers

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.

like image 84
Valentin Shergin Avatar answered Sep 21 '22 09:09

Valentin Shergin