简体   繁体   中英

Use both Garbage Collector and ARC in objective c

I have read that Garbage collection is done in objective c using AUTOZONE(LIBAUTO).

Also garbage collector is available upto OS X 10.8. While studying i was thinking what is the need of ARC if garbage collector is available. Then from the sources on stackoverflow.com, i learned the difference between ARC and garbage collector and advantages of both over each other.

Now i know that ARC works at compile time and garbage collector works at run time. Also ARC is not able to release memory of CFTypes, it only works for objective C types. And Garbage collector could release retain cycles that couldn't be done using ARC.

Now i wanted to know that can we use both ARC and garbage collector together, since both are available in os x 10.7. Also why is garbage collector deprecated after 10.8. Is ARC an alternative to garbage collector and it can release every kind object that was done by garbage collector.

Also since garbage collector was not available in ios, then what was used in ios before ARC for garbage collection. Is manual memory management is able to manage everything if done correctly, and there is no need of garbage collection if Manual memory management is taken care of correctly?

As far as I know there is no (easy) way to enable both, and it wouldn't make sense anyway.

You already almost answered the question yourself: both GC and ARC serve the same purpose, cleaning up memory. GC has the advantage of catching things that ARC cannot, but it has a runtime penalty. With ARC, you can still leak memory if you don't use it correctly but if done right (mostly: you adhere to the naming conventions), ARC has the major advantage of freeing you from the manual management burden with excellent runtime performance.

So you chose either one or the other, it doesn't really make sense to mix them. If you have GC enabled, all the work that ARC is doing would be almost useless and thus wasting performance.

BTW, before ARC, we did manual memory management using retain / release . In fact, that is still an option and still used widely (for example, I work on a huge project which would be cumbersome to convert to ARC).

In C memory management is often performed with malloc and free. In C++ new and delete is the preferred method. Both of these rely on the developer knowing exactly what memory they have allocated, where (stack vs heap) and they must handle releasing that memory only once!

This becomes awkward if two objects reference the same, other object; which one is responsible for cleaning up that object?

Objective-C decided to solve that problem with retain /release, which manages an internal reference count to the object. When that count is zero, the object is deleted and its memory released. This method is commonly implemented manually by developers with C and C++ or automatically with smart pointers.

Looking at the development of Objective-C, Apple are constantly driving towards making the language simpler to use and less vulnerable to common errors, by automating boilerplate code.

Therefore, the next step from manually handling retain and release was GC, but as already mentioned, there is overhead at runtime for when the GC will run. A GC binary is completely different and incompatible with reference counting, both manual and automatic (ARC). This is why when developing a System Preferences bundle, GC still must be enabled, because the host application (System Preferences) continues to use GC, even in Mavericks. Forgetting to compile a 3rd party preference bundle with GC will cause the load of the bundle to fail.

The development of ARC reverts back to the model of retain / release, but the compiler handles this for the developer, making the code much simpler to write and far easier to read. Apple is likely to continue along this path and each year I expect Objective-C to become more refined.

That's the advantage of being able to define both the compiler and language for which it works.

The downside to this, in my opinion, is that as the language develops, it's harder for developers new to the language to find documentation that doesn't reference old features, especially when trawling the web for example code. Trying to decipher the compiler errors caused can be a huge source of frustration to a developer who is new to Objective-C.

You can't mix ARC and GC, because the objective-c runtime disallow it, as several concepts are incompatible with each other:

  • The way the GC works is that -retain/release/autorelease/... do nothing anymore, and to make up for that fact, a new concept was introduced which is -finalize;
  • The way ARC works is that you should not replace -retain/release/autorelease, and the compiler issues them for you (and not using [object retain] directly but lower level things that work only if you haven't replaced -retain/release/autorelease).

Those reasons really mean that the ABI of GC and ARC are very different, and non compatible.

ARC and MRR are compatible (in the sense that you can mix code built with ARC on and code built with standard MRR); GC and MRR are compatible, since basically, MRR calls are ignored if you run in GC mode; but GC and ARC aren't.

And when I say that the runtime disallow it, it means that at runtime, if the app that loads the frameworks is a GC app running in GC mode, no framework can have been written with ARC because those don't support GC and cannot be loaded for the App.

As a side effect, it means that the Apple frameworks that support GC are either written using CF or MRR, no ARC for them, the poor souls.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM