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

为什么在iOS 6应用程序中自动释放和发布窗口?,ios,objective-c,Ios,Objective C,自从iOS3之后,我就没有做过任何iOS开发,所以我的记忆有点模糊(尽管我从来没有想过要进行内存管理,我的想法也很清楚) 我正在启动一个新项目,不明白为什么框架代码的结构是这样的: - (void)dealloc { [_window release]; [super dealloc]; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *

自从iOS3之后,我就没有做过任何iOS开发,所以我的记忆有点模糊(尽管我从来没有想过要进行内存管理,我的想法也很清楚)

我正在启动一个新项目,不明白为什么框架代码的结构是这样的:

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

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[[UIWindow alloc]
                    initWithFrame:[[UIScreen mainScreen] bounds]]
                   autorelease];
    // ... snip ...
}
  • 为什么窗口对象会自动释放?我敢肯定,在较旧的iOS版本中,这种方式从未出现过
  • \u window
    来自哪里?这只是访问
    [自窗口]
    的另一种方式吗
  • 我会这样写:

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

    我总是被灌输永远不要释放自动释放的对象,事实上这样做通常会导致分割错误。

    在第二个示例中,您正在泄漏窗口对象,因为
    alloc
    将给对象一个保留计数1,您可以通过属性指定它
    \u窗口
    ,该属性还将保留指定给它的对象

    确实,您不应该释放autorelease对象,但是在dealloc中,您正在释放
    窗口
    属性的iVar。您应该始终释放任何声明为retain或strong的属性。(尽管在使用ARC时不是这样)。
    \u窗口
    现在自动生成为属性
    窗口
    的iVar

    有些人认为不应该在
    init
    dealloc
    中使用
    self.
    属性。 因此,我的做法是:

     [_window release], _window = nil;
    
    这将在释放
    \u窗口后将其设置为nil,确保如果任何其他线程可能希望使用此窗口,它将调用
    nil
    。这可以防止崩溃,但也可能造成一些奇怪的行为。这完全取决于你


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

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


    仍然不清楚
    \u窗口
    变量,但我假设它只是一个快捷方式。

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

    遵循您的代码路径

  • [UIWindow alloc]
    =重新计算1
  • 自动释放=重新计数0
  • 设置self.window会影响重新计数,重新计数现在为1,并且在
  • dealloc
    中,您释放它,因此retainCount=0,对象被删除
  • 您可能没有注意到,在以后的iOS SDK中,自动合成的属性会自动创建带有下划线前缀的实例变量。因此,您也可以在
    dealoc
    中执行
    self.window=nil

    一,。为什么窗口对象会自动释放?我敢肯定,在较旧的iOS版本中,这种方式从未出现过

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

     self.window  = [[[UIWindow alloc] ....]autorelease];
    
    self.
    语法允许调用setter函数,该函数只保留一次对象。因此,我们使用
    [UIWindow alloc]
    分配的实际窗口对象应该被释放,因此
    自动释放
    。retain using
    self.
    语法在dealloc中概念性地发布。因此,对于一个alloc加一个retain,我们将发布两次

    窗户从哪里来?这只是另一种访问方式吗
    [自窗口]


    这个问题已经讨论过了,正如我在回答中所说的,
    \u窗口
    是属性
    窗口
    的ivar。我真的建议使用strong over retain使您的代码经得起未来的考验。你应该认真研究一下ARC,它会为你节省很多时间和头疼。你可能已经找到了答案,但万一你还没有找到。您声明的任何属性都不再需要合成,它是可选的。如果您不@synthesis属性,则会自动创建一个ivar,并将下划线作为第一个字符。干杯,伙计。我现在对所有闪亮的新东西都有点了解了:)