Note that there are some explanatory texts on larger screens.

plurals
  1. PO"Modifying layer that is being finalized" in ARC only on iOS 4
    text
    copied!<p>On iOS5 my app runs all day, no issues. On iOS 4.3 as soon as I try to switch view, the app starts spewing 'Modifying layer that is being finalized', pointing to the CALayer of the view that was just dealloc'd until I kill the program or it crashes out itself.</p> <p>The app I'm building has about 8 minigames, and each game consists of a single view. I have a main view controller and in that class I keep a reference to the current game's view.</p> <pre><code>UIView* currentView; </code></pre> <p>The main view is completely empty. A view is loaded into it by calling essentially this:</p> <pre><code>SomeView*someView = [[SomeView alloc]initWithFrame:self.bounds]; someView.delegate = self; currentView = someView; [self.view addSubview:currentView]; </code></pre> <p>What I'm noticing is that on iOS 4 a removeFromSuperview is called on Dealloc, but on iOS 5 it isn't. So my dealloc methods are all this:</p> <pre><code>NSLog(@"Dealloc Game Name"); if (([[[UIDevice currentDevice] systemVersion] floatValue] &gt; 4.9)){ [self removeFromSuperview]; } </code></pre> <p>The dealloc method seems to be called every time I either call</p> <pre><code>currentView = nil; </code></pre> <p>or</p> <pre><code>currentView = someOtherView; </code></pre> <p>This is consistent between iOS4 and iOS5. </p> <p>Also consistent is that if I call </p> <pre><code>[currentView removeFromSuperview]; </code></pre> <p>the view in currentView is deallocated, so that when I follow that with</p> <pre><code>'currentView = nil;' or 'currentView = someOtherView;' or even '[self setCurrentView:bacon];' </code></pre> <p>The app crashes because it tries to send another release to the already released view in currentView.</p> <p>If I turn NZZombies off, I get this Backtrace from the EXC_BAD_ACCESS crash.</p> <pre><code>2012-02-27 15:50:46.631 Keyboard[36378:207] Dealloc Splatter 2012-02-27 15:50:46.718 Keyboard[36378:207] modifying layer that is being finalized - 0x5a17900 (gdb) bt #0 0x001e7b99 in CALayerCommitIfNeeded () #1 0x001e7bc4 in CALayerCommitIfNeeded () #2 0x001e7bc4 in CALayerCommitIfNeeded () #3 0x0018d4f1 in CA::Context::commit_transaction () #4 0x0018e294 in CA::Transaction::commit () #5 0x0018e46d in CA::Transaction::observer_callback () #6 0x0166889b in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ () #7 0x015fd6e7 in __CFRunLoopDoObservers () #8 0x015c61d7 in __CFRunLoopRun () #9 0x015c5840 in CFRunLoopRunSpecific () #10 0x015c5761 in CFRunLoopRunInMode () #11 0x021961c4 in GSEventRunModal () #12 0x02196289 in GSEventRun () #13 0x005f3c93 in UIApplicationMain () #14 0x000027d0 in main (argc=1, argv=0xbfffecc4) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/main.m:16 </code></pre> <p>My results are always the same, I've tried declaring currentView a few different ways, without a property, and as a property.</p> <pre><code>@property(nonatomic,strong)__strong UIView* currentView; @property(nonatomic,unsafe_unretained) UIView* currentView; </code></pre> <p>As I understand from scouring the docs and SO, an unsafe_unretained property should nil itself on dealloc, just like the weak reference that isn't compatible with iOS 4? If so, I must not be doing that correctly, because it still tries to release itself twice. </p> <p>These calls are also all being made in methods called with performSelectorOnMainThread, so I'm probably not in a background thread at any point.</p> <p>I feel like I have a misunderstanding of ARC at some low level that I just haven't been able to puzzle out on my own. Any ideas?</p> <p>Oh, one other thing. The one game that I wrote with -fno-objc-arc flag on switches out fine on iOS 4, and I'm really just hoping I don't need to go back and convert all the minigames away from ARC. </p> <p>Edit for More Info: Sometimes instead of EXC_BAD_ACCES error, I get this which I think is pointing to the UIView which owns the CALayer that is pointed to in the "Modifying layer that is being finalized" warning:</p> <pre><code>malloc: *** error for object 0xa3012e4: incorrect checksum for freed object - object was probably modified after being freed. *** set a breakpoint in malloc_error_break to debug </code></pre> <p>Also, the Analyzer tool points out zero possible mistakes when analyze the code from clean.</p> <p><strong>Update:</strong></p> <p>I did exactly what k1th suggested, and stepped through the code. The only difference is i used self.currentView instead of currentView, and added 'readwrite' to it's property declaration as Rob Napier suggested. It did basically the same thing. On calling [currentView removeFromSuperview] the first 'Dealloc Splatter' you see is printed. That is the only line of code in the dealloc from this run through, NSLog(@"Dealloc splatter");</p> <p>On calling currentView = someView the Dealloc is again called, which prints 'Dealloc Splatter' again, and then promptly crashes out as it hits the end of the function. Here's the stack trace. I've verified this by stepping through this code line by line three times.</p> <pre><code>2012-02-27 19:13:58.138 Keyboard[36828:207] call switch 2012-02-27 19:14:00.481 Keyboard[36828:207] SwitchViews 2012-02-27 19:14:13.980 Keyboard[36828:207] Dealloc Splatter 2012-02-27 19:14:20.234 Keyboard[36828:207] Dealloc Splatter (gdb) bt #0 0x01a43098 in objc_msgSend () #1 0x0061e361 in -[UIView dealloc] () #2 0x00025818 in -[CanvasView dealloc] (self=0xa330dd0, _cmd=0x57dfea2) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/Paint Splatter/CanvasView.m:54 #3 0x000062db in -[MenuViewController setCurrentView:] (self=0xa305170, _cmd=0x415f2, currentView=0x5c36920) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:21 #4 0x00004ee9 in -[MenuViewController launchVisualizer:] (self=0xa305170, _cmd=0x41517, sender=0x0) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:180 #5 0x00d6befc in -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] () #6 0x00d7e506 in -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] () #7 0x0000423a in -[MenuViewController switchViews:] (self=0xa305170, _cmd=0x415d3, number=0x5c2c560) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:70 #8 0x00d6c94e in __NSThreadPerformPerform () #9 0x016688ff in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ () #10 0x015c688b in __CFRunLoopDoSources0 () #11 0x015c5d86 in __CFRunLoopRun () #12 0x015c5840 in CFRunLoopRunSpecific () #13 0x015c5761 in CFRunLoopRunInMode () #14 0x021961c4 in GSEventRunModal () #15 0x02196289 in GSEventRun () #16 0x005f3c93 in UIApplicationMain () #17 0x00002890 in main (argc=1, argv=0xbfffecc4) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/main.m:16 </code></pre> <p>Doing this with NSZombies Enabled has this result, CanvasView is Splatter, as is 0x5c2f020:</p> <pre><code>2012-02-27 19:26:15.480 Keyboard[36856:207] call switch 2012-02-27 19:26:18.072 Keyboard[36856:207] SwitchViews 2012-02-27 19:26:20.921 Keyboard[36856:207] Dealloc Splatter 2012-02-27 19:26:23.884 Keyboard[36856:207] *** -[CanvasView release]: message sent to deallocated instance 0x5c2f020 2012-02-27 19:26:28.365 Keyboard[36856:207] *** NSInvocation: warning: object 0x5c2f020 of class '_NSZombie_CanvasView' does not implement methodSignatureForSelector: -- trouble ahead 2012-02-27 19:26:28.365 Keyboard[36856:207] *** NSInvocation: warning: object 0x5c2f020 of class '_NSZombie_CanvasView' does not implement doesNotRecognizeSelector: -- abort </code></pre> <p>and here is it's backtrace</p> <pre><code>#0 0x015f8709 in ___forwarding___ () #1 0x015f8522 in __forwarding_prep_0___ () #2 0x000062db in -[MenuViewController setCurrentView:] (self=0xab0aad0, _cmd=0x415f2, currentView=0x5c1f9e0) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:21 #3 0x00004ee9 in -[MenuViewController launchVisualizer:] (self=0xab0aad0, _cmd=0x41517, sender=0x0) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:180 #4 0x00d6befc in -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] () #5 0x00d7e506 in -[NSObject(NSThreadPerformAdditions) performSelectorOnMainThread:withObject:waitUntilDone:] () #6 0x0000423a in -[MenuViewController switchViews:] (self=0xab0aad0, _cmd=0x415d3, number=0x5d2a960) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/MenuViewController.m:70 #7 0x00d6c94e in __NSThreadPerformPerform () #8 0x016688ff in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ () #9 0x015c688b in __CFRunLoopDoSources0 () #10 0x015c5d86 in __CFRunLoopRun () #11 0x015c5840 in CFRunLoopRunSpecific () #12 0x015c5761 in CFRunLoopRunInMode () #13 0x021961c4 in GSEventRunModal () #14 0x02196289 in GSEventRun () #15 0x005f3c93 in UIApplicationMain () #16 0x00002890 in main (argc=1, argv=0xbfffec98) at /Users/tjfallon/Documents/iOS Projects/Dropbox/Working Directory/Keyboard/Keyboard/main.m:16 </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload