In MRC, you were responsible for keeping track and making sure that all references of objects were incremented, decremented and deallocated properly. In Obj-C you have basically a set of rules to help you not get any memory leaks or dangling pointers, and it was a considerable effort to make sure that everything was working great, and that could've been automated by something, like some other languages used to.
That's is when ARC get's into the game.
ARC came as an incisive alternative to how things worked with MRC. With ARC, instances are deallocated when there's no strong reference to them, and every instance keeps track of the number of strong and weak/unowned references kept to itself. Although it might look like a similar behaviour, the amount of effort used in both cases are hugely different, in MRC you had to keep track of everything, whereas in ARC the only thing you should do is avoid retain cycles.
Some differences between ARC and Garbage Collector are:
- Garbage collector is part of the runtime structure. In ARC, the Swift compiler does code-cleaning and reference tracking insertion in your app bundle.
- Garbage collector does not reclaims the memory as soon as the instance loses its references, ARC does.
- If some objects cycle (or graph) has references to themselves, but are not accessible through the root node, GC can clean the hole graph, whereas in ARC they would never get deallocated because they hold strong references to it other(retain cycle).
If you want to check for more information, I've found this article to be very helpful:https://swift007blog.wordpress.com/2017/01/14/what-is-arc-in-ios/