【问题标题】:sent to deallocated instance发送到解除分配的实例
【发布时间】:2010-03-04 04:59:42
【问题描述】:

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

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

【问题讨论】:

  • 请将代码发布到您遇到此崩溃的确切位置。如果你知道如何使用 NSZombieEnabled 断点然后使用它,你就会知道我们崩溃的原因可能是什么。
  • @Man: "message sent to deallocated instance" 表示 Zombie 已启用。
  • 问题是,没有代码崩溃的地方,我可以回溯一下。

标签: iphone objective-c calayer retain


【解决方案1】:

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

祝你好运!

【讨论】:

  • 我已经这样做了,它说 CALayer 是 malloc'd 的行是 [[NSBundle mainBundle] loadNibNamed@"..." 等。这并没有真正的帮助,因为我已经多次经历过那个笔尖并且什么都没有释放两次。
【解决方案2】:

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

【讨论】:

  • 当你说它是一个类 (m/xib) 的 dealloc 函数中的双重释放时,你的意思是你在 m 文件和 XIB 文件中释放?我有一个类似的问题 - UIView 通过 XIB 加载,它的自定义 UIView 子类。在我的 UIView 子类中,我正在释放一个属性,它会因与您遇到的相同错误而崩溃。如果我把它注释掉,一切都很好。甚至可以在 XIB 中解除分配吗?
  • 我遇到了这个错误,也是因为 IBOutlet 被释放了两次。看起来像 [myLabel 发布]; [myLabel 发布]; (字面意思是彼此相邻)。释放后将变量分配为 nil 的最佳实践,这里没有这样做,否则错误不会出现。很难追踪,但幸运的是这个视图控制器的代码非常小。
  • 这非常有用。谢谢。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

    我遇到了同样的错误,这是因为我使用buttonWithType(例如[UIButton buttonWithType:UIButtonTypeRoundedRect])创建了一个UIButton,然后发布了它。这是错误的,因为buttonWithType 已经包含autorelease。所以我删除了我的release,错误就消失了。

    【讨论】:

      【解决方案5】:

      追踪哪个视图真的很有帮助!如果您知道框架以及哪些超级层和子层与该视图相关,这可能非常简单......如果您记录所有层,它只是为了搜索并找到相同的内存地址。祝你好运! :)

      将此类别添加到您的应用程序中

      类别标题:

      #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
      

      来自例如电话应用代理

      [CALayer swizzle];
      

      【讨论】:

      • 这确实是一个很好的调试方法。谢谢!
      【解决方案6】:

      我偷偷怀疑它与自动释放池有关...

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-05-11
          • 2013-06-04
          • 2012-04-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多