Re: ARC Retain Cycles
Re: ARC Retain Cycles
- Subject: Re: ARC Retain Cycles
- From: Andy Lee <email@hidden>
- Date: Mon, 21 Apr 2014 16:09:51 -0400
On Apr 21, 2014, at 10:53 AM, Alex Zavatone <email@hidden> wrote:
>
> On Apr 21, 2014, at 10:34 AM, Andy Lee wrote:
>
>> On Apr 21, 2014, at 8:27 AM, Dave <email@hidden> wrote:
>>> Also, when I did this, I left the property attributes as “retain” and “assign”, I’m wondering if it would be better to change them to “strong” and “weak” ? Although, AFAIK this shouldn’t make a difference?
>>
>> For object properties, "strong" is a synonym for "retain", but "assign" is different from "weak". Weak properties are automatically set to nil when the object they reference goes away. If you use "assign" for an object property, it will not be automatically nil'ed and you may end up with a garbage pointer.
>>
>> "weak" is not supported in 10.6 or 10.7, I forget which. If you need to support an OS version that supports ARC but not "weak", you should use the qualifier "unsafe_unretained" rather than "assign". It behaves the same, but it expresses intention better, plus you can later do a global replace to use "weak" when you decide to drop support for that old OS. In this case it's up to you to nil out that object property at the appropriate time.
>
> In that case, is it any significant overhead in simply using strong?
I haven't studied the particulars, but my understanding is that it's weak references that add overhead. A strong property basically does for us what we used to do by hand when writing accessor methods. I'd *guess* it's no slower than that, and possibly sometimes faster due to optimizations in ARC. On the other hand, to manage a weak property, the runtime has to know where all the weak references are so it can nil them after all the strong references go away. And I suspect their may be synchronization issues which cost additional overhead to manage.
Most of the time we want properties to be strong, because the reason for *having* the property is to hold on to a reference to the object. But making *all* properties strong leads to the problem of retain cycles -- objects having strong references to each other, either directly or through a cycle of intermediate objects. Retain cycles lead to memory leaks, because nobody in the cycle will ever have its retain count go to zero, even when all strong references from outside the cycle have gone away.
The solution is to use a weak reference for one of the properties in the cycle. In general, if one object conceptually "owns" the other, then the "owning" object uses a weak reference and the "owned" object uses a strong one. For example, a parent has weak references to its children, and the children have strong references back to the parent. Similarly, a delegating object has a weak reference to its delegate, which typically (though not necessarily) has a strong reference back to the delegator.
These examples should be familiar from manual memory management. When implementing the delegate pattern under retain/release, the recommended practice is to have objects not retain their delegate, for the same reason of avoiding retain cycles.
> In a case of rapidly allocating objects that are strongly linked and weakly linked, are there any tests that have been published to show the overall impact on performance, memory overhead, etc?
>
> I've got time to perform some simple tests, but no time to do anything terribly robust.
>
> Are any of you aware of anything out there?
You might try Googling "Marcel Weiher ARC" -- I see this as one search result:
<http://mjtsai.com/blog/2013/09/10/arc-vs-mrc-performance/>
Also I'd suggest poking around on Mike Ash's blog in case he discusses ARC performance (not sure if he does).
--Andy
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden