114

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?

nhgrif
  • 58,130
  • 23
  • 123
  • 163
KMC
  • 18,443
  • 53
  • 146
  • 238
  • The memory management model is still relevant even though you are using ARC. You still have to understand reference counting, you just don't have to do it manually. So your last paragraph is an unreasonable demand. – jrturton Feb 13 '12 at 14:56
  • https://stackoverflow.com/questions/53699976/memory-management-attribute-when-using-class-type-property-in-objective-c-arc/53703259#53703259 – Arjun Patel Dec 10 '18 at 10:07

6 Answers6

509

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.

BJ Homer
  • 47,750
  • 10
  • 111
  • 128
  • 2
    It's based off an analogy Malcom Crawford at Apple gave a few years back. Don't know where he got it. – BJ Homer Feb 13 '12 at 15:14
  • I remember reading something similar (pre-arc) in a book, think it was Hillegass, but then he could have got it from somewhere else... it's a good one though! – jrturton Feb 13 '12 at 15:15
  • Apparently, @mmalcc's example was actually something different, and I'm misremembering. So yeah. Hillegass, though I don't think I got it directly from his book. – BJ Homer Feb 13 '12 at 15:19
  • 14
    +1 excellent example. it's a derivative of Hillegass's example on how leashes are retain/release, but I love this adaptation for strong/weak. – Dave DeLong Feb 13 '12 at 15:32
  • it's worth mentioning that weak pointers are only zeroed out if you're using garbage collection (Mac only), or are using ARC on 10.7+/iOS 5+. They are *not* zeroed out using ARC on 10.6. – Dave DeLong Feb 13 '12 at 15:42
  • 2
    @DaveDeLong: Well, they're *illegal* on 10.6 with ARC. You can't use them at all. So that's kinda an irrelevant point. – BJ Homer Feb 13 '12 at 15:43
  • 5
    Another good one is Helium balloons: as long as at least one string is held, it's not going to float away. The leash/balloon analogies are also good at getting people to forget that "ownership" is managed by retain/release. – Steve Weller Feb 13 '12 at 15:44
  • +1 for the idea for my new book title: See Spot Get Deallocated. – memmons Mar 30 '13 at 18:08
  • +1 FOR the dog example, very impressive. Weak: "keep this as long as someone else points to it strongly" should read as "will return the weak reference as long as someone else points to it strongly, otherwise, it would be nil" – Ethan Wang Sep 12 '13 at 10:21
  • @BJHomer: **Wow!** Such a succinct, yet effective analogy. It definitely cleared up any lingering confusion I could have possibly had and is a great way to help visualize it. Got here from the iOS development tutorial on Udacity. +1 – John Dorlus May 07 '15 at 14:47
  • Excellent example ! It helped me to understand better – Rizwan Ahmed Oct 06 '15 at 06:00
  • @BJHomer Excellent example Thanks for it – Parth Kapadia Jan 26 '16 at 13:12
  • @BJHomer thanks for the wonderful explaination i have added in my website it http://9to5ios.com/simplest-way-to-define-property-and-synthesize-in-objective-c/ – 9to5ios Jul 11 '18 at 09:54
34

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"]

mattjgalloway
  • 34,372
  • 12
  • 95
  • 108
  • 1
    So the main difference between strong and weak is that deallocation of objects being pointed at strongly will automatically nil-out all related weak pointers. And for a weak pointer to point to something, there always exist a strong pointer. If so, the main application object has to be strongly pointed to? – KMC Feb 13 '12 at 15:29
  • For a weak pointer to point to something *valid* then yes there must be a strong pointer. Add to that the fact that iOS 5 and Lion support auto-nilling of weak references and you get what you say. iOS 4's runtime does *not* support that though. The "main application object" I assume you mean the `UIApplication` object? That will be strongly referenced by the inner workings of `UIKit` - but you don't need to worry about that. – mattjgalloway Feb 13 '12 at 15:48
  • I think you can use the word like as "strongObjectPointer" instead of "strongObject". So New people to programming will have better meaning. Nice catch on @BJ Homer post Mr.Matt.Interesting:) – Vijay-Apple-Dev.blogspot.com Jul 06 '13 at 15:25
2

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.
Shashi3456643
  • 1,991
  • 15
  • 20
  • It's worth mentioning here what the retain cycle typically is. We have two objects: object A and object B. Object A has a strong reference to object B and object B has a strong reference to object A. Nothing else has a strong reference to object A or B. – boro Dec 26 '14 at 10:56
2

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.

RobotCharlie
  • 873
  • 11
  • 16
1

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.

Peter Wone
  • 15,594
  • 12
  • 74
  • 106
1

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.

Gabriel
  • 3,289
  • 1
  • 13
  • 20