3

自 iOS 3 以来我没有做过任何 iOS 开发,所以我的记忆有点模糊(尽管内存管理从来都不是我为之苦苦挣扎的事情,而且我对此很清楚)。

我正在开始一个新项目,但不明白为什么骨架代码的结构是这样的:

- (void)dealloc
{
    [_window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc]
                    initWithFrame:[[UIScreen mainScreen] bounds]]
                   autorelease];
    // ... snip ...
}
  1. 为什么窗口对象会被自动释放?我很确定在旧的 iOS 版本中从来没有这样过。
  2. 从哪里来_window?这只是另一种访问方式[self window]吗?

我会这样写:

- (void)dealloc
{
    [self.window release];
    [super dealloc];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc]
                   initWithFrame:[[UIScreen mainScreen] bounds]];
    // ... snip ...
}

我总是鼓吹永远不要释放自动释放的对象,实际上这样做通常会导致分段错误。

4

4 回答 4

2

在您的第二个示例中,您正在泄漏窗口对象,因为alloc它将为对象提供保留计数 1,您_window通过属性分配它,该属性也将保留分配给它的对象。

确实,您不应该释放自动释放对象,但在 dealloc 中,您正在释放window属性的 iVar。您应该始终释放任何声明为保留或强的属性。(虽然不是在使用 ARC 时)。现在_window自动生成为属性的 iVar window

有些人认为您不应该在or中使用self.属性。因此,我这样做的方式是:initdealloc

 [_window release], _window = nil;

这将_window在释放它后将它设置为 nil,确保如果任何其他线程可能想要使用它,它将调用 on nil。这可以防止崩溃,但也可能会产生一些奇怪的行为。这完全取决于你。


您应该移至 ARC,这是一个编译器选项,可在编译时为您添加发布/自动租赁。如果您在使用 ARC 时正确设置了属性,则无需自行添加这些属性。

于 2013-01-24T10:19:56.723 回答
0

所以我想通了(大部分)。@property声明具有strong属性。显然,这对 ARC 来说是新的(我实际上并没有使用它),否则只是 的别名retain,因此self.window = [ ... ]保留了对象,因此自动释放。

仍然不清楚_window变量,但我认为这只是一个捷径。

于 2013-01-24T10:20:13.197 回答
0

检查window属性内存描述符是什么样的。我假设它是strong/retain在这种情况下,当您设置window属性时,它的值被保留,因此需要在dealloc.

遵循您的代码路径。

  1. [UIWindow alloc]= 保留计数为 1。
  2. 自动释放 = 保留计数为 0
  3. 设置 self.window 会影响现在 = 1 并且一直存在的 retainCount,直到...
  4. dealloc你释放它时,retainCount = 0 并且对象被删除

您可能错过了在后来的 iOS SDK 中,自动合成属性会自动创建带有下划线前缀的实例变量。所以你也可以self.window = nil在你的dealloc.

于 2013-01-24T10:20:54.943 回答
0

1、为什么window对象会被自动释放?我很确定在旧的 iOS 版本中从来没有这样过。

如果窗口对象没有自动释放,那么它会导致泄漏。由于您正在使用

 self.window  = [[[UIWindow alloc] ....]autorelease];

self.语法允许调用 setter 函数,它会保留对象一次。所以我们分配使用的实际窗口对象[UIWindow alloc]应该被释放,因此autorelease。使用self.语法的保留在概念上在 dealloc 中发布。因此,对于一个分配加一个保留,我们释放了两次。

_window 从何而来?这只是另一种访问方式吗 [self window]

那么这个问题已经在这里讨论过了

于 2013-01-24T10:23:39.970 回答