In the good old Objective-C, what should you know about ARC?

Original address: medium.com/flawless-ap…

Original author:

Published: July 4, 2019-6 minutes to read

In recent days, I’ve searched iOS for more about memory management. This is a difficult Swift topic for me to understand. So I decided to dig a little deeper into the good old Objective-C — because I was already learning it — to learn more about memory management, to dig into the topic. Like, what was it like before ARC? What happened after it? And what is the difference between ARC and Garbage Collector…… And so on.

The introduction

An interesting thing happens when you start working with objects.

Objects are more memory intensive than primitive types such as integers and floating point numbers. This is true whether the objects come from your own classes or from objects you create from classes in the Apple framework.

Fortunately, we don’t have to worry about manually handling memory addresses and manually allocating or reallocating memory areas (which is still true for some languages). Instead, in Objective-C, we use something called reference counting.

What does reference counting mean?

When your application starts, an area of memory becomes available to your objects. So you create an object, and you allocate a memory area for that object. Now, the variable holding that object is a pointer to that object. Specifically, a pointer to an area of memory. What happens next is that when an object is created, it is given what is called a retention count or reference count, which represents the number of owners of a particular object. Therefore, we can think of it as one, as shown below.

The variable that calls var is a pointer to a block of memory. So, in your program, you can work with this pointer and call methods on it if you want. But when you get to the end of the code block. This variable is no longer accessible or accessible to any part of the program. The retention count is zero again, because there is now nothing pointing to that block of memory. When the retention count goes to zero, the run-time engine says, here’s a block of memory that no one cares about. Therefore, it frees up the memory block so that it can be used by other objects.

What could possibly go wrong?

The only problem here might be if you create objects and pass them from one place to another. So it’s not clear that the pointer is still in range. Until 2011, when ARC (automatic reference counting) was added, you had to write statements about when you were done using the object.

Before the ARC

This is something we had to do before ARC was added to Objective-C.

MyClass *myObject = [[MyClass alloc] init];
[myObject myMethod]; // call methods.// doing some stuff with the object
[myObject release]; // releasing the object
Copy the code

We’re going to write a little bit of code to create an object. It will be created. We’re going to call a method on that object. But at some point, we must explicitly call a release declaration. And this will be responsible for taking the retention count down.

This is not a problem for a small number of objects. But when you have hundreds of objects being created, manipulated, used as arguments, passed from one object to another… You have to track them. If you pass an object from one area of the program to another, you may not even be sure you can release it. Or whether some other part of the program is responsible for releasing it, maybe even before you finish it. So you can also write what’s called a reserved call to that object. But you still need to match an extra release call for any reserved calls.

Basically, before ARC, you must envision every possible scenario your application will go through – logic to ensure that the lives of all your objects are properly managed. It’s not that easy.

After the ARC

Fortunately, when using ARC, you no longer need to use the Release AutoRelease retain call. But it’s important to understand the dangers of writing this code incorrectly.

One of the problems you may run into is that you may release too quickly. You’re going to create an object, you’re going to have a pointer to that memory region, you’re going to call methods, and at some point you’re going to release it. But if you still have a valid pointer, there’s really nothing to stop you from writing another line of code to use it. This will be called a dangling pointer. A pointer exists, but what it points to is no longer valid in memory, which can cause a crash.

Conversely, you might not release at all, you might create an object. It starts calling methods on the object and then disappears as the pointer exits scope. But you never release the object, so you start claiming more and more memory, which is called a memory leak.

So writing a lot of code like this can be very error-prone and problematic. Now you might be wondering, if we’re using this new ARC feature, why I even mention the existence of such a thing as release and preserve calls. Because the concept of releasing and reserving calls hasn’t gone away, languages still do reference counting.

The language has not changed. The difference is that you don’t need to write the save and release and auto-release calls at all, because the compiler already writes them. ARC is taking advantage of the fact that compilers have become very good, and any time you build your project, the compiler, in this case LLVM, which is what Xcode uses behind the scenes, is able to determine all possible paths for your code. It basically synthesizes the write, save, release, and auto-release calls you need from your code.

What the compiler is doing is essentially writing the same code that you would write yourself if you were really, really, really good at writing memory management code. ARC doesn’t actually change your source code files, but that’s actually what the compiler does when you compile a project and you’re using ARC.

Difference between garbage collector and ARC

ARC has a very different effect than having a garbage collector. Languages that use the garbage collector are often so-called nondeterministic. This means that you cannot tell exactly when an object is being reclaimed because it is managed by an external process at run time. ARC allows us to achieve complete certainty. The code controls when these objects are released. It’s just that the code to release them is already written by the compiler, not by you. In fact, when you use ARC, not only do you not write these calls, you can’t write these calls either. If you try to make even a simple release call, you’ll get an error.

conclusion

You need to know the idea of retaining or releasing. It’s still the following, but if you haven’t done it, be thankful you don’t have to do it anymore. I’d love to hear more from you on this topic, what do you think about going back to a language like Objective-C in order to better understand topics like memory management? Have you ever done anything like this before?


www.deepl.com translation