1

I've done a bit of reading and I've found a lot about how things are, but not why:

From what I have read, automatic reference counting makes memory management a lot easier than it would have been in the past. As I understand it, it is analogous to garbage collection in Java, the difference being that it is taken care of at compile time not run time. I.e. the compiler inserts code that keeps track of how many references an object has, then deallocates it when this count hits 0.

In the code I've written so far I've had quite a few problems with objects vanishing due to ARC deallocating them because I hadn't used a strong reference. My take away from these problems is... always always always use a strong reference!

So my question is why do weak references even exist? I.e. when would I as a developer ever want a reference to an object that I can't rely on not being deallocated without my knowledge?

jscs
  • 62,161
  • 12
  • 145
  • 186
Chris
  • 5,566
  • 9
  • 42
  • 57
  • 2
    Java has weak references, you know. :) – Matt Ball Apr 30 '14 at 15:41
  • 2
    FYI - ARC is not analogous to garbage collection. ARC is simply the compiler automatically adding calls to `retain` and `release` for you. It is completely different from garbage collection. – rmaddy Apr 30 '14 at 15:43
  • Perhaps the most common example is when Object A has Object B as its delegate. Object A needs to use object B but it does not own it, and thus it would be weak. – Gruntcakes Apr 30 '14 at 15:44
  • TIL! Still no wiser why they even exist or why I would ever use them. – Chris Apr 30 '14 at 15:46
  • See the 2nd answer here: http://stackoverflow.com/questions/8927727/objective-c-arc-strong-vs-retain-and-weak-vs-assign – rmaddy Apr 30 '14 at 15:46
  • @rmaddy Analogous != Equal ;) I did explain that I understood they solve the same problem, but differently, i.e. at *compile* time. – Chris Apr 30 '14 at 15:48
  • 2
    The most common reason for `weak` is to avoid reference cycles. – rmaddy Apr 30 '14 at 15:48
  • Your question is not really about iOS its about Object Oriented design. The principles of strong and weak (even the terms themselves) are independent of iOS. If you are struggling with when to use weak and when strong then perhaps stepping back and reading some basic OO design/implementation tutorials will help. – Gruntcakes Apr 30 '14 at 15:58
  • 1
    In short, you should use `strong` for those objects that you own (or those objects that you absolutely to need to ensure the object isn't released when the owner is done with it). Use `weak` for those objects that you don't own, but simply want a reference to them. In terms of why you use `weak`, see [Use Weak References to Avoid Retain Cycles](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html#//apple_ref/doc/uid/TP40004447-1000810) section in the _Advanced Memory Management Programming Guide._ – Rob Apr 30 '14 at 16:41

1 Answers1

2

Reference counting is not garbage collection.

In a reference counting system like Cocoa Touch, the system deallocates an object when its reference count becomes zero.

Now consider writing an app that uses a UITableView. You have to provide an object to act as the table view's data source. You will probably use your UIViewController subclass as the data source.

Your view controller probably has a reference to the table view. That means the table view's reference count is at least 1.

Your table view needs a reference to its data source. That means the view controller has a reference count of at least 1.

Suppose the view controller is no longer referenced by anything except the table view, and the table view is no longer reference by anything except the view controller. It is impossible for your program to ever use these objects again, because it has no path of references it can follow that will lead to either object. We can say that the objects are “inaccessible”. Even then, neither of the objects can be destroyed, because each has a reference count of 1.

In Cocoa Touch, this scenario is called a retain cycle. A retain cycle is bad (unless it will be broken automatically when some event happens, like a timer firing or a touch ending), because it prevents the system from destroying objects that will never be used again.

This is in fact the difference between reference counting and garbage collection: a GC collects all objects that your program can no longer access. A reference counting system collects all objects that have a reference count of zero.

You could try to write your program to notice when the view controller and table view are no longer needed. When that happens, you could explicitly break the retain cycle (for example, by setting the table view's data source to nil). But in general it's hard to know when none of the objects is reachable. (That is why garbage collectors are so nice: they do the hard work for you.)

In Cocoa Touch, to prevent the retain cycle in the table view example, the table view references its data source “weakly”. It keeps a reference to the data source, but it doesn't increment or decrement the data source's reference count. So when the view controller and the data source both become unreachable, the table view's reference count is still 1 (because the view controller has a strong reference to it), but the view controller's reference count is 0. So the system deallocates the view controller. During deallocation, the view controller gives up its reference to the table view, which makes the table view's reference count zero, so the system can also deallocate it.

In truth, the table view doesn't use an ARC weak reference (as far as I know). It uses what ARC calls an __unsafe_unretained reference, because it was written long before ARC. But you should use ARC weak references in your code, because they are much safer and more useful.

rob mayoff
  • 342,380
  • 53
  • 730
  • 766
  • Thanks, that explanation was really helpful! – Chris Apr 30 '14 at 16:01
  • `__unsafe_unretained` is so-named because under ARC, normal `weak` references are automatically assigned a value of `nil` once their referenced object gets deallocated. Since you can message `nil` in Objective-C, this can help prevent crashes (typically). `__unsafe_unretained` references don’t contribute to the retain count, but if you message one after it has been deallocated, you will get an `EXC_BAD_ACCESS` error (probably). – Zev Eisenberg Apr 30 '14 at 16:02