代码之家  ›  专栏  ›  技术社区  ›  Ben Scheirman

当我“正确”释放推送的视图控制器时,iPhone崩溃

  •  0
  • Ben Scheirman  · 技术社区  · 17 年前

    我有一个基于导航控制器的应用程序,我遇到了一个奇怪的问题,我的一些视图控制器推送在“弹出”视图控制器时导致崩溃。

    我已经将其缩小到将视图控制器推到导航控制器堆栈上后释放视图控制器的代码行。

    我的代码如下所示:

    SomeViewController *viewController = [[SomeViewController alloc] init];
    [self.navigationController pushViewController:viewController animated:YES];
    [viewController release];  //offending line
    

    现在这个 是 正确的内存管理代码,但不幸的是,我收到了“双重免费发送到实例0x…”错误(在某些情况下),我的应用程序崩溃。这通常发生在我弹出所说的视图控制器时。

    我在寻找关于看什么的建议。我卡住了。

    提前谢谢。

    编辑 :下面是Louis建议的堆栈跟踪转储的结果。

    在第一个版本中,retain计数是13(我猜是由于CocoaTouch基类中的一些代码)。最终,问题归结到:

    2009-08-06 22:33:18.304 My App [26601:20b] ** RELEASE CALLED **
    2009-08-06 22:33:18.306 My App [26601:20b] Retain count was : 1
    0   My App                              0x000033ec start + 4700
    1   CoreFoundation                      0x302042e8 CFRelease + 136
    2   CoreFoundation                      0x30227249 CFNumberGetValue + 2937
    3   CoreFoundation                      0x30204421 _CFRelease + 241
    4   Foundation                          0x30506515 NSPopAutoreleasePool + 341
    5   QuartzCore                          0x00b5436e
                                            CA_CGRectUnapplyInverseTransform_ +
                                            19738
    6   QuartzCore                          0x00b54109
                                            CA_CGRectUnapplyInverseTransform_ +
                                            19125
    7   CoreFoundation                      0x302454a0 CFRunLoopRunSpecific + 3696
    8   CoreFoundation                      0x30244628 CFRunLoopRunInMode + 88
    9   GraphicsServices                    0x32044c31 GSEventRunModal + 217
    10  GraphicsServices                    0x32044cf6 GSEventRun + 115
    11  UIKit                               0x309021ee UIApplicationMain + 1157
    12  My App                              0x00002258 start + 200
    13  My App                              0x000021c6 start + 54
    14  ???                                 0x00000001 0x0 + 1
    2009-08-06 22:33:18.307 My App [26601:20b] ########### DEALLOC
    
    #
    objc[26601]: FREED(id): message retainCount sent to freed
    

    如果我省略了上面有问题的行(viewController release];),那么retain计数仅为2,并且实例永远不会被释放。

    1 回复  |  直到 17 年前
        1
  •  0
  •   Louis Gerbarg    17 年前

    它正在其他地方发布。如果您想知道是谁在调用它,您可以在对该类的释放调用时中断。另一个选项是在发行版中打印堆栈跟踪:

    #include <execinfo.h>
    #include <stdio.h>
    
    - (void) release {
      void* callstack[128];
      int i, frames = backtrace(callstack, 128);
      char** strs = backtrace_symbols(callstack, frames);
      for (i = 0; i < frames; ++i) {
        printf("%s\n", strs[i]);
      }
      free(strs);
    
      [super release];
    }