每当我将一个视图控制器推到我的堆栈上,然后将其弹出,我收到此错误:
*** -[CALayer retainCount]: message sent to deallocated instance <memory address>
似乎恰好在弹出的视图控制器上调用dealloc
之后发生,并且仅对此视图控制器是独占的。我确定CALayer与视图本身有关,因为我不使用它们。
有什么想法吗?
编辑: 这是回溯
(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)
答案 0 :(得分:12)
我有类似的问题;结果我没有正确地保留UIButton。我是如何找到原因的: - 启用僵尸 - 使用'Allocations'仪器运行项目 - 使用该应用程序触发错误 - 检查Instruments在时间线上显示消息“Zombie Messaged” - 应该有一个链接打开CALayer详细信息:分配和解除分配时 - 你对分配的地方感兴趣,应该是啊啊!放在你的代码中
祝你好运!答案 1 :(得分:7)
这有点棘手,我的是在一个类(m / xib)的dealloc函数中的双重释放,我在tableview中作为行样式。仪器没有对该对象有太多了解,但检查callstack 确实有助于确定哪一个类是-1。
答案 2 :(得分:4)
我有类似的问题。我的问题是在接口中声明的一个对象变量被错误地声明为(nonatomic, assign)
而不是(nonatomic, retain)
,就像它应该的那样。这导致释放消息被发送到已经具有保留计数0(=崩溃)的对象。
答案 3 :(得分:3)
我遇到了同样的错误,因为我使用buttonWithType
(例如[UIButton buttonWithType:UIButtonTypeRoundedRect]
)创建了UIButton并在之后发布了它。这是错误的,因为buttonWithType
已包含autorelease
。所以我删除了release
,错误消失了。
答案 4 :(得分:1)
追踪哪个视图真有帮助!如果您知道框架以及哪个超级层和子层与该视图相关,那么这可能非常简单......如果您记录所有图层,那么只需搜索并找到相同的内存地址即可。祝好运! :)
将此类别添加到您的应用程序
类别-部首:
#import "CALayer+debug.h"
@interface CALayer (Debug)
-(NSString*)debugDescription;
-(NSString*)debugLayerTree;
@end
类别-实现:
#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
来自例如的appdelegate
[CALayer swizzle];
答案 5 :(得分:0)
我怀疑它与自动释放池有关......
答案 6 :(得分:0)
我得到了同样的错误。我创建了一个UIView
对象来保存两个按钮,然后我将其添加到导航项rightBarButtonItem
中。问题是我使用工厂buttonWithType
方法创建按钮,但我只是alloc
和initWithFrame
我的视图。然后,在我完成视图后,我发布了它,之后系统试图释放两个按钮(已经发布的UIView
的子视图) - 崩溃 - 它正在向已经发送消息释放按钮。希望能帮助别人节省一些类似的麻烦。