Explanation of strong and weak storage in iOS5

Memory ManagementIos5Automatic Ref-Counting

Memory Management Problem Overview


I am new to iOS5 development and using objective-c. I have trouble understanding the difference between strong and weak storage. I have read the documentation and other SO questions, but they all sound identical to me with no further insight.

I read the documentation: Transitioning To ARC - it references to iOS4 terms of retain, assign, and release; which confuses me. Then I look into Open U CS193p, where it differentiates strong and weak:

> Strong: "keep this in the heap until I don't point to it anymore"
> Weak: "keep this as long as someone else points to it strongly"

Aren't the two definition identical = if pointer no longer pointing to an object, then free the memory holding the object? I understand the concept of pointers, heap, allocation or deallocation of memory - but what's the difference between strong and weak?

Memory Management Solutions


Solution 1 - Memory Management

The difference is that an object will be deallocated as soon as there are no strong pointers to it. Even if weak pointers point to it, once the last strong pointer is gone, the object will be deallocated, and all remaining weak pointers will be zeroed out.

Perhaps an example is in order.

Imagine our object is a dog, and that the dog wants to run away (be deallocated).

Strong pointers are like a leash on the dog. As long as you have the leash attached to the dog, the dog will not run away. If five people attach their leash to one dog, (five strong pointers to one object), then the dog will not run away until all five leashes are detached.

Weak pointers, on the other hand, are like little kids pointing at the dog and saying "Look! A dog!" As long as the dog is still on the leash, the little kids can still see the dog, and they'll still point to it. As soon as all the leashes are detached, though, the dog runs away no matter how many little kids are pointing to it.

As soon as the last strong pointer (leash) no longer points to an object, the object will be deallocated, and all weak pointers will be zeroed out.

Solution 2 - Memory Management

> Aren't the two definition identical.

Absolutely not. The key difference in the two definitions that you've pointed out is the "as long as someone else". It's the "someone else" that is important.

Consider the following:

__strong id strongObject = <some_object>;
__weak id weakObject = strongObject;

Now we've got a two pointers to <some_object>, one strong and one weak. If we set strongObject to nil like so:

strongObject = nil;

Then if you go through the rules you outlined then you'll ask yourself these questions:

  1. Strong: "keep this in the heap until I don't point to it anymore"

    strongObject doesn't point to <some_object> any more. So we don't need to keep it.

  2. Weak: "keep this as long as someone else points to it strongly"

    weakObject still points to <some_object>. But since nobody else points to it, this rule also means that we don't need to keep it.

The result is that <some_object> is deallocated and if your runtime supports it (Lion and iOS 5 upwards) then weakObject will automatically be set to nil.

Now consider what happens if we set weakObject to nil like so:

weakObject = nil;

Then if you go through the rules you outlined then you'll ask yourself these questions:

  1. Strong: "keep this in the heap until I don't point to it anymore"

    strongObject does point to <some_object>. So we do need to keep it.

  2. Weak: "keep this as long as someone else points to it strongly"

    weakObject doesn't point to <some_object>.

The result is that <some_object> is not deallocated, but weakObject will be the nil pointer.

[Note that all that is assuming <some_object> is not pointed to by another strong reference somewhere else / some other means of being "held"]

Solution 3 - Memory Management

Strong

  1. Creates ownership between property and assigned value.
  2. This is default for object property in ARC so it does not let you worrying about reference count and release the reference automatically.
  3. It is replacement for retain. We use if and only if we need to use as retain.

Weak

  1. Creates non-ownerships between property and assigned value.
  2. Strong is used on parent object and weak is used on child object when parent is released then child object reference is also set to nil
  3. It helps to prevents retain cycles.
  4. It doesn't protect the referenced object when collection by garbage collector.
  5. Weak is essentially assigned, unretain property.

Solution 4 - Memory Management

Another example: Student is an Object, supposed that she/he can graduate(deallocate) as long as she/he finished all core-courses(strong pointers), no matter if she/he take optional-courses(weak pointers). In other words: strong pointer is the only factor of deallocation of that Object.

Solution 5 - Memory Management

No, they aren't identical but very different. You use strong only if you need to retain the object. You use weak on any other case, with de advantage that you can know if object ha been removed from heap because nobody is retaining it.

Solution 6 - Memory Management

I know I'm rather late to this party, but I think it's important to confuse the issue by pointing out that the meaning of "strong and weak memory models" depends on whether you are talking about software or hardware.

For hardware, weak or strong indicates whether there is support for sequential consistency.

> [SC means that]...the result of any execution is the same as if the operations of all > the processors were executed in some sequential order, and the > operations of each individual processor appear in this sequence in the > order specified by its program. - Lamport, 1979

WTF does that have to do with memory? It implies that writes to variables by different processors have to be seen in the same order by all processors. In hardware with a strong model this is guaranteed. On hardware with a weak model, it isn't.

Existing answers interpret the question only in terms of software memory models. Hardware is not irrelevant to programming. This very question mentions iOS, which typically runs on Arm7 processors. Arm7 has a weak memory model. For programmers accustomed to processors with a strong model - which is all of us because x86 and x64 have a strong model - this is a terrible trap. Using a bool to signal another thread to exit works fine in a strong model. The same code on Arm doesn't work at all unless you mark the flag volatile, and even then it's erratic.

While it is true that Arm8+ changes this utterly with explicit support for acquire/release, legacy software doesn't use this support. Legacy software includes all three phone OSs and everything that runs on them, as well as compilers and libraries until they are updated.

For an extended examination of this topic I refer you to the inimitable Herb Sutter.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKMCView Question on Stackoverflow
Solution 1 - Memory ManagementBJ HomerView Answer on Stackoverflow
Solution 2 - Memory ManagementmattjgallowayView Answer on Stackoverflow
Solution 3 - Memory ManagementShashi3456643View Answer on Stackoverflow
Solution 4 - Memory ManagementRobotCharlieView Answer on Stackoverflow
Solution 5 - Memory ManagementGabrielView Answer on Stackoverflow
Solution 6 - Memory ManagementPeter WoneView Answer on Stackoverflow