为什么在iOS 6应用程序中自动释放并释放窗口?

时间:2013-01-24 10:07:30

标签: ios objective-c

自从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]的另一种方式吗?
  3. 我写的是:

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

    我总是将从不发布到自动发布的对象中,实际上这样做通常会导致分段错误。

4 个答案:

答案 0 :(得分:2)

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

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

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

 [_window release], _window = nil;

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


您应该转到ARC,这是一个编译器选项,可以在编译时为您添加release / autolease。如果在使用ARC时正确设置属性,则无需添加这些属性。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

遵循您的代码路径。

  1. [UIWindow alloc] = retainCount为1。
  2. autoreleasing = retainCount of 0
  3. 设置self.window会碰到现在= 1的retainCount,直到......
  4. dealloc中释放它,因此retainCount = 0且对象被删除
  5. 您可能错过了在以后的iOS SDK中,自动合成属性会自动创建带有下划线前缀的实例变量。因此,您也可以在self.window = nil中执行dealloc

答案 3 :(得分:0)

  

1。为什么窗口对象会被自动释放?我很确定它在旧的iOS版本中从未像现在这样。

如果窗口对象未自动释放,则会导致泄漏。因为你正在使用

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

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

  

_window来自哪里?这只是另一种访问方式   [self window]

这个问题已经讨论过了here