Skip to content

Instantly share code, notes, and snippets.

@davertay
Last active January 3, 2016 05:08
Show Gist options
  • Save davertay/8413402 to your computer and use it in GitHub Desktop.
Save davertay/8413402 to your computer and use it in GitHub Desktop.
Setting a view's layer contents to nil causes subview layers to be dealloc'd rdar://15811803
Summary:
When a view is removed from it's superview and subsequently dealloc'd, if it sets it's layer.contents = nil this will cause all subview layers to be dealloc'd even though those subviews retain a pointer to their layer. Any attempt to send messages to those subviews that references the view's layer (now a zombie) will crash the app.
The attached example is of course contrived, however the real world problem caused by this is when using CATiledLayer which has async drawing. It is a requirement to set layer.contents to nil in the view dealloc in order to block until any remaining drawing blocks are completed.*
*Yes I know that if dealloc is being called how can there still be active drawing blocks? Because of rdar://8640386 that's how
Steps to Reproduce:
1. Add a view to the window (view1)
2. Add a subview (view2) to view1 and retain it
3. Remove view1 from the window
4. In view1's dealloc method set it's layer.contents to nil
5. Observe view2's layer is now a zombie
Attached is a simple project to reproduce the issue.
Expected Results:
Expect the subview's layer to be retained
Actual Results:
Subview's layer is a zombie. Tears ensue. Hair is pulled out.
Version:
iOS 7.0.3 (11B508)
Notes:
This is triggered by setting the layer.contents to nil, which is something we do to workaround rdar://8640386
Configuration:
iOS 7 Simulator or device
Attachments:
'TestViewRemove.zip' was successfully uploaded.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment