Do variables in functions have strong references to their objects, or can they be deallocated in the runtime of a function body?

Viewed 72

I'm guessing the answer is no, but I'm having a difficult time finding a straight answer. For example:

func doSomething() {
  let thing = Things.sharedInstance.list[0]

  if let maybeProperty = thing.property { // Program Crashes EXC bad memory access error
    // Do something with property
  }
}

Is list as a class property the only strong reference, while thing inside a function (in a class) does not hold a strong reference / increment the reference count? Therefore, in a race condition between the assignment and the optional unwrapping variable assignment, the underlying thing can be deallocated?

Thanks! :)

1 Answers

Do variables in functions have strong references to their objects?

Yes, thing will keep a strong reference to Things.sharedInstance.list[0]

Can they be deallocated in the runtime of a function body?

It depends on the context.

  • If your code runs on a single sequential thread, the object thing points to will never be deallocated in the middle of function execution.
  • If your code runs on multiple threads or concurrently, it can happen (I guess it's your case)

The problem here is that we are racing, modifying the object thing points to from multiple threads or concurrently. Leading to the two threads interleave operations like this:

CURRENT THREAD    |      OTHER THREAD
-------------------------------------
                  | Remove or replace
                  | list[0] (called
                  | object)
                  |
Load pointer to   |
object            |
                  |
                  | Reduce reference
                  | count of object
                  |
                  | Free object
                  |
Increase reference|
count of object   |
(!)               |
                  |
Access property   |
from object (!)   |
                  |

Lots of problems can happen here but normally, you will get a crash according to Apple document for Automatic Reference Counting

If ARC were to deallocate an instance that was still in use, it would no longer be possible to access that instance’s properties, or call that instance’s methods. Indeed, if you tried to access the instance, your app would most likely crash.

Related