18

每当我将视图控制器推送到我的堆栈上,然后将其弹出时,我都会收到此错误:

*** -[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) 
4

7 回答 7

12

我有类似的问题;原来我没有正确保留 UIButton。我如何找到原因: - 启用僵尸 - 使用“分配”工具运行项目 - 使用应用程序触发错误 - 检查工具是否在时间线上显示消息“僵尸消息” - 应该有一个打开 CALayer 详细信息的链接:当它被分配和解除分配 - 你对分配的地方感兴趣,应该是啊哈!放在你的代码中

祝你好运!

于 2010-09-28T21:30:01.710 回答
7

这有点棘手,我是在一个表视图中作为行样式的一个类 (m/xib) 的 dealloc 函数中的双重发布。Instruments 没有显示太多关于该对象的信息,但检查调用堆栈确实有​​助于查明哪个类是要 -1 的。

样本

于 2011-03-02T17:32:27.290 回答
4

我有一个类似的问题。我的问题是接口中声明的对象变量之一被错误地声明为(nonatomic, assign)而不是 as (nonatomic, retain),因为它应该是。这导致将释放消息发送到保留计数为 0(= 崩溃)的对象。

于 2010-11-16T14:38:14.233 回答
3

我遇到了同样的错误,这是因为我使用(eg ) 创建了一个UIButton并在之后发布了它。这是错误的,因为已经包含了。所以我删除了我的,错误消失了。buttonWithType[UIButton buttonWithType:UIButtonTypeRoundedRect]buttonWithTypeautoreleaserelease

于 2011-05-03T22:45:54.403 回答
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];
于 2011-11-28T13:29:20.560 回答
0

我有一个偷偷摸摸的怀疑它与自动释放池有关......

于 2010-03-04T12:24:10.810 回答
0

我遇到了同样的错误。我制作了一个UIView对象来保存两个按钮,然后将其添加到导航项的rightBarButtonItem. 问题是我使用工厂buttonWithType方法来创建按钮,但我只是allocinitWithFrame我的观点。然后,在我完成视图之后,我正在释放它,后来,当系统试图释放两个按钮(已释放的子视图UIView)时 - 崩溃 - 它正在向已经释放的按钮发送消息。希望这将帮助某人在类似的麻烦上节省一些时间。

于 2011-11-07T11:45:02.243 回答