> On Dec 6, 2016, at 11:44 AM, Carl Hoefs <newsli...@autonomy.caltech.edu> 
> wrote:
> 
> I get the following crash in my iOS 9 app simply by adding a CALayer to the 
> current view controller's self.view.layer and then dismissing the current 
> view controller. Simplified code:
> 
>    @property (strong,nonatomic) CALayer *layer;
>    .  .  .
>    _layer = [[CALayer alloc] init];
>    [_layer setDelegate: self];
>    [self.view.layer addSublayer:_layer];
> 
> Upon dismissing the VC:
> 
>    [self dismissViewControllerAnimated:YES completion:nil];
> 
> The following exception occurs:
> 
> (lldb) bt
> * thread #1: tid = 0x121bd, 0x22c2c68a libobjc.A.dylib`objc_retain + 10, 
> queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, 
> address=0xb0000010)
>    frame #0: 0x22c2c68a libobjc.A.dylib`objc_retain + 10
>    frame #1: 0x27a2a22a UIKit`-[UIView(Hierarchy) subviews] + 330
>    frame #2: 0x27b3e1ea UIKit`discardEngineRecursive + 118
>    frame #3: 0x27a2fd06 UIKit`-[UIView dealloc] + 630
>    frame #4: 0x2336cd98 CoreFoundation`-[__NSDictionaryM dealloc] + 132
>    frame #5: 0x22c2cf8a libobjc.A.dylib`objc_object::sidetable_release(bool) 
> + 150
>    frame #6: 0x22c2d3cc libobjc.A.dylib`(anonymous 
> namespace)::AutoreleasePoolPage::pop(void*) + 388
>    frame #7: 0x23363f30 CoreFoundation`_CFAutoreleasePoolPop + 16
>    frame #8: 0x23415c56 CoreFoundation`__CFRunLoopRun + 1598
>    frame #9: 0x233641c8 CoreFoundation`CFRunLoopRunSpecific + 516
>    frame #10: 0x23363fbc CoreFoundation`CFRunLoopRunInMode + 108
>    frame #11: 0x24980af8 GraphicsServices`GSEventRunModal + 160
>    frame #12: 0x27a9c434 UIKit`UIApplicationMain + 144
>  * frame #13: 0x001b655e ProteinFold`main(argc=1, argv=0x0043bbc8) + 122 at 
> main.m:14

This is due to the confluence of a few UIKit implementation details. The bottom 
line is that UIKit is trying to iterate the subviews of your view controller’s 
view, encounters your layer, and tries to retain the layer’s delegate. Because 
the layer’s delegate is assign (not weak) and the view controller has already 
been deallocated, this explodes taking your app with it.

Your safest bets are to either clear the delegate of the layer at an 
appropriate time (possibly in your view controller’s dealloc is all that is 
necessary), or to use a UIView instead of a raw CALayer in this case. Removing 
the layer would also suffice, as that would prevent UIKit from seeing it at the 
time in question. Making the layer weak is probably causing your reference to 
deallocate before it can be added to the layer tree, which is why it doesn’t 
display in that case.

> 
> If I remove the CALayer first before the 
> -dismissViewControllerAnimated:completion:, it doesn't crash:
> 
>    [layer removeFromSuperlayer];
> 
> Why do I need to explicitly remove my added CALayer before dismissing the VC? 
> Note: If I declare layer as weak, the crash does not occur, but neither does 
> the layer display onscreen.
> -Carl
> 
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> 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:
> https://lists.apple.com/mailman/options/cocoa-dev/david.duncan%40apple.com
> 
> This email sent to david.dun...@apple.com

--
David Duncan


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to