全局声明的自动释放静态对象在内存中存活多长时间?

Cod*_*da1 1 memory-management objective-c ios

如果我在全局范围的类文件中声明一个静态对象句柄.分配给此句柄的对象是自动释放的对象.那么在我的应用程序生命周期中,此对象将在内存中保留多长时间?

jus*_*tin 5

如果我在全局范围的类文件中声明一个静态对象句柄.分配给此句柄的对象是自动释放的对象.那么在我的应用程序生命周期中,此对象将在内存中保留多长时间?

简答:您希望您的全球成为强有力的参考.在MRC中,您必须为全局变量添加保留和释放.在ARC中,全局隐含强大(ARC为您添加它们).

长答案:在ARC下,您的静态全局变量是一个强大的参考.在MRC中,您将在设置时保留此变量,然后释放上一个对象.如果你没有,那么你可以在它被释放后(悬空指针)访问它.

因为它是一个强引用,所以你的对象将保持有效,直到a)全局变量的强引用被放弃并且b)自动释放池被耗尽c)当然,任何其他强引用都被放弃了.

因此,如果您正在使用针对该全局的强引用,并且您永远不会重新分配它(逻辑上,放弃全局的强引用),那么您的对象将永远不会被dealloc编辑.

当您使用不安全的非重定义语义(通过ARC中的装饰,或staticMRC中的默认语义)时,将-dealloc在当前自动释放池耗尽并删除所有强引用时编辑该对象.这是用程序(MRC)最简单的说明;

static MONObject * GlobalObject;
//
// In MRC, you must add the reference counting to ensure you do not end up with a dangling
// pointer, so false is what how your program should be written in MRC.
//
// In ARC, your program will look like NonRetainedOwnership because it treats the global
// as a strong reference.
static const bool NonRetainedOwnership = ...T/F...;

...

// assume GlobalObject is accessed from one thread only -- i won't bother with
// the supporting code to illustrate how this should be made thread safe.
- (MONObject *)sharedObject
{
 if (nil == GlobalObject) {
  if (NonRetainedOwnership) {
      // don't do this! lifetime will be determined by strong client references
      // and the reference you rely on now will be lost when the thread's current
      // autorelease pool is drained -- leaving you with a dangling pointer which
      // will cause issues when -sharedObject is called again.
    GlobalObject = [[MONObject new] autorelease];
  }
  else {
     // Good - keep a strong reference:
   GlobalObject = [MONObject new];
  }
 }
 return GlobalObject;
}

- (void)disposeSharedObject
{
 if (NonRetainedOwnership) {
  GlobalObject = nil;
 }
 else {
  // remove our reference, which was established at [MONObject new]
  // assuming there are no strong external references, the object
  // will be dealloc'ed -- but you should not make that assumption
  // if you return it.
  [GlobalObject release], GlobalObject = nil;
 }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果NonRetainedOwnership为true并且您使用MRC,那么您的对象通常会-dealloc-sharedObject返回后不久进行(假设任何被调用的对象-sharedObject都没有强引用).在这种情况下,"很快"意味着池通常会在当前的callstack中耗尽几帧,当你在主线程上时通常在AppKit或UIKit中,因为我没有看到很多人在主要线程上显式创建自动释放池线.borrrden在"1/60秒"之后说,假设在主线程的运行循环中创建并自动释放对象(如果我错了,请纠正我).'Kits在主运行循环的每次迭代中创建自动释放池,但是您的程序可能在辅助线程上运行,或者可能有内部自动释放池,因此生命周期可能更短或更长.通常情况下,你不需要深入思考这些事情 - 只需在这里使用强引用,因为你真的没有办法确保这个全局变量正确发生.

如果您只是简单地写:@autoreleasepool{[[MONObject new] autorelease];} NSLog("Hi");那么该对象将(在正常情况下)在NSLog被调用时被释放.