C ++和Objective-C自动释放问题

时间:2010-10-04 10:50:56

标签: c++ objective-c objective-c++

我有三层,底层是用C ++编写的,另外两层是中间层和顶层都在Objective-C中。

C ++层存储对中间层中类的引用,中间层还存储对顶层中类的引用。

在从中间层接收到请求时,底层负责异步调用中间层中的方法,该方法又调用顶层中的方法。

不幸的是,我的代码报告的错误如下:

* _NSAutoreleaseNoPool():类NSCFNumber的对象0x523e50自动释放,没有池到位 - 只是泄漏 堆栈:(0x95c83f0f 0x95b90442 0x28d3 0x2d42 0x95b96e0d 0x95b969b4 0x93a00155 0x93a00012)

问题是顶层中的方法是从没有自动释放池的C ++ POSIX线程调用的。我能提出的唯一解决方案是在中间层添加以下内容:

bool temp = false;

- (void) method ...
{
  if (!temp)
  {
    temp = true;
    NSAutoreleasePool *arPool = [[NSAutoreleasePool alloc] init];    
  }

  call_to_the_top_layer();
}

这很有效。我的问题是,还有其他更好的解决方案吗?这太丑了......

2 个答案:

答案 0 :(得分:3)

总是分配一个自动释放池,没问题。但是你还需要释放池,否则就会出现内存泄漏:

- (void) method
{
  NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

  // start doing some work, for example:
  call_to_the_top_layer();

  [pool release];
}

您始终可以创建池,但必须在同一块中释放它。通常你不需要这样做,除非你创建一个新线程,或者有时在循环中分配大量的临时值,以避免垃圾堆积过多并填满内存。

答案 1 :(得分:2)

据我了解你的问题,你在一个调用中间层的线程中有底层。正如您已经发现的那样,如果您想使用Cocoa框架(它不是关于Objective-C;),您必须拥有自动释放池。

您应该在创建线程时创建一个,或者为每个中间层请求创建一个并释放一个。您的“解决方案”确实创建了一个按需生效,直到线程结束时

哪一个最好取决于您的架构:

  • 线程有多长?
  • 在整个生命中只有一个自动释放池是否可以?

<强>更新

当您释放临时池时,您应该知道可能发生的异常:

id pool = [[NSAutoreleasePool alloc] init];
@try {
    …
} @finally {
    [pool release];
}

如果您拥有/使用Objective-C异常DarkDust的回答是正确的方法。