why delegates should be unsafe_unretained and not weak?

447 views Asked by At

I added ARC to an app I'm working on. Unfortunately, it crashes. I found that the automatic script which updates all apps to ARC gave __unsafe_unretained qualifier to all id< protocolName> type.

  1. Why isn't it a weak type? I have deployed the app and all its sub-projects to iOS 5, and therefore I do have weak qualifiers.

  2. My main problem is if I declare those delegates as strong, I'll have a retain-cycle. If I do not, the next time I call them they will be zombies. I checked and before my app crash, the delegate is NSZombie.

What is the cause of this crash and how can it be prevented?

2

There are 2 answers

0
yonivav On BEST ANSWER

Took some time but i solved it:

  1. I deployed the .xcodeproj projects to iOS 5, but the targets were left in iOS 4.3 deployment. When i fixed it (it's in the 'build settings' for each target) - i could change all '__unsafe_unretained' to '__weak', and all 'unsafe_unretained' to 'weak'.

  2. To avoid retain cycle those delegates should be weak, and they won't be zombies anymore (because they are weak and not unsafe_unretained), and the app won't crash anymore.

If i was still using iOS4.3-, and there isn't unsafe_unretained qualifer, i should only assign nil to those delegates after i don't need them anymore.

0
Ron On

The qualifiers __unsafe_unretained and week have quite a few things in common. They both won't increase the retain count for example. If for example a view controller holds an __unsafe_unretained IBOutlet to a UIView and you remove that very UIView from the view hierarchy, then you (given that you don't retain the view anywhere else) will decrease the retain count and most likely dealloc the UIView. The pointer however will still point to that location and is left dangling. Not nice but also not problematic if you know what happened. Weak properties help you avoiding dangling pointers by nullifying the property when the object gets to a retain count of 0.

Now, if your app crashes or the properties show up as zombies, then they are being released - by whichever class though.

One statement that is not entirely correct is that if you retain the property instead, you'll create a retain cycle. There is the possibility of creating retain cycles though but it really depends on your implementation, not just the property declaration. When you retain an object, you take ownership and until you're done with that object, prevent it from being deallocated by increasing its retain count. If your delegate gets released already while you hold a weak pointer, you won't prevent it from being released. I am assuming you deal with modal view controllers here - UIPopoverController to be precise (just a guess).

You should use instruments and look at the lifecycle of your object and see who retains/releases it. It could be helpful to know. Otherwise, you could paste some code and maybe there will be a nice person here to help you find the issue.

cheers Ronny