问题
Whenever I push a view controller onto my stack, then pop it off, I get this error:
*** -[CALayer retainCount]: message sent to deallocated instance <memory address>
It seems to happen right after dealloc
is called on the view controller that is being popped off and is exclusive to only this view controller. I'm sure the CALayer has something to do with the view itself, as I do not use them.
Any ideas?
Edit: Here is the backtrace
(gdb) bt
#0 0x01fcd3a7 in ___forwarding___ ()
#1 0x01fa96c2 in __forwarding_prep_0___ ()
#2 0x01fc10e8 in CFGetRetainCount ()
#3 0x01cbc770 in CA::release_root_if_unused ()
#4 0x01cbc707 in x_hash_table_remove_if ()
#5 0x01cbc4ec in CA::Transaction::commit ()
#6 0x01cc4838 in CA::Transaction::observer_callback ()
#7 0x01fa5252 in __CFRunLoopDoObservers ()
#8 0x01fa465f in CFRunLoopRunSpecific ()
#9 0x01fa3c48 in CFRunLoopRunInMode ()
#10 0x027dd615 in GSEventRunModal ()
#11 0x027dd6da in GSEventRun ()
#12 0x0057cfaf in UIApplicationMain ()
#13 0x00002dec in main (argc=1, argv=0xbfffeed0)
回答1:
I had similar issue; turns out I was not retaining a UIButton properly. How I found the cause: - Enable zombies - Run the project with 'Allocations' instrument - Use the app to trigger the bug - Check that Instruments show message 'Zombie Messaged' on the timeline - There should be a link that opens CALayer details: when it was allocated and deallocated - You are interested in the place where is was allocated, should be that aha!!! place in your code
Good luck!
回答2:
This is a little bit tricky, mine was a double release in a dealloc function of one of the classes (m/xib) I had in a tableview as a row style. Instruments didn't show much about the object, but checking the callstack was really helpful to pinpoint what class was the one going to -1.
回答3:
I had a similar issue. My problem was that one of the object variables declared in the interface was mistakenly declared with (nonatomic, assign)
and not as (nonatomic, retain)
, as it should have been. This caused a release message to be sent to an object already with a retain count of 0 (= crash).
回答4:
I had the same error and it was because I created an UIButton by using buttonWithType
(e.g. [UIButton buttonWithType:UIButtonTypeRoundedRect]
) and released it afterwards. This was wrong because buttonWithType
has already an autorelease
included. So I removed my release
and the error was gone.
回答5:
Tracking down which view is really helpfull! It can be pretty trivial if you know the frame and which superlayers and sublayers is related to that view... If you log all layers it is just to search-and-find that same memory address. Good luck! :)
Add this category to your application
Category-Header:
#import "CALayer+debug.h"
@interface CALayer (Debug)
-(NSString*)debugDescription;
-(NSString*)debugLayerTree;
@end
Category-Implementation:
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import "CALayer+debug.h"
#import <UIKit/UIKit.h>
#import <objc/runtime.h>
#import <objc/message.h>
@implementation CALayer (Debug)
//....
void Swizzle(Class c, SEL orig, SEL new)
{
Method origMethod = class_getInstanceMethod(c, orig);
Method newMethod = class_getInstanceMethod(c, new);
if(class_addMethod(c, orig, method_getImplementation(newMethod), method_getTypeEncoding(newMethod)))
class_replaceMethod(c, new, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
else
method_exchangeImplementations(origMethod, newMethod);
}
+ (void)swizzle {
Swizzle([self class], @selector(init), @selector(newInit));
}
- (id)newInit {
self = [self newInit];
[self performSelector:@selector(log) withObject:self afterDelay:0.5];
return self; // calls old method
}
- (void)log {
NSLog(@"%@", [self debugDescription]);
}
- (NSString *)debugDescription {
return [NSString stringWithFormat:@"%@ frame=%@ zAnchor=%1.1f, superlayer: %@>", [self description], NSStringFromCGRect(self.frame), self.zPosition, self.superlayer];
}
@end
Call from e.g. appdelegate
[CALayer swizzle];
回答6:
I have a sneaking suspicion it has to do with the auto release pool...
回答7:
I was getting the same error. I made a UIView
object to hold two buttons, which I then added to my navigation item's rightBarButtonItem
. The problem is I used the factory buttonWithType
method to create the buttons, but I just alloc
and initWithFrame
my view. Then, after I was done with the view, I was releasing it and later, when the system was trying to release the two buttons (subviews of the already released UIView
) - crash - It was sending a message to the already released buttons. Hope that will help somebody to save some time on similar kinds of trouble.
来源:https://stackoverflow.com/questions/2376979/sent-to-deallocated-instance