【问题标题】:Why do we have [NSString string] when we can write [NSString new]?当我们可以写 [NSString new] 时,为什么我们有 [NSString string]?
【发布时间】:2014-03-17 08:28:24
【问题描述】:

显然我不只是指 NSString;有[NSDictionary dictionary][NSArray array] 等等。但是,当我们可以发送[NSDictionary new][NSArray new] 等时,为什么还要使用所有这些方法呢?

【问题讨论】:

标签: cocoa-touch cocoa constructor


【解决方案1】:

原因主要是历史原因,因为两者的区别在于创建对象的引用计数;自动引用计数几乎完全消除了对引用计数的关心。

+string and methods like it 返回不属于调用者的对象(它们在自动释放池中)。另一方面,+new"four NARCs" 之一,它确实创建了拥有引用。

在 ARC 之前,您会选择在特定情况下具有您需要的内存管理含义的那个。现在,您可以使用任何您喜欢的。您的代码级别没有区别。

在某些循环情况下,您可能会发现使用+new 更可取,因为与+string 相比,still does apparently 缩短了对象的生命周期。

【讨论】:

  • 实际上,new 是 ARC 的首选,因为这样在分配大量代码块时就不需要@autoreleasepool { ... }
  • 您确定构造函数仍将其结果放入池中吗,@LeoNatan? objc_retainAutoreleasedReturnValue() 可以避免这种情况。
  • 我也是这么想的,但不是:stackoverflow.com/questions/21172044/…
【解决方案2】:

补充 Josh 的好答案,在使用 ARC 时,首选使用 alloc] init]new,因为您不再需要 @autoreleasepool { ... } 来释放自动释放压力。

考虑以下代码:

for(int i = 0; i < X; i++)
{
    //@autoreleasepool {
    NSMutableArray* array = [NSMutableArray array];

    for(int j = 0; j < Y; j++)
    {
        [array addObject:[NSString stringWithFormat:@"%d", j]];
    }

    ///Do something with array.

    //}
}

随着XY 的增长,您会发现内存在增长,并且需要@autoreleasepool,因为只有在自动释放池耗尽时才会释放对象。

现在考虑

for(int i = 0; i < X; i++)
{
    NSMutableArray* array = [NSMutableArray new];

    for(int j = 0; j < Y; j++)
    {
        [array addObject:[[NSString alloc] initWithFormat:@"%d", j]];
    }

    ///Do something with array.
}

这里的对象一旦超出范围就会被释放并且不再保留。

【讨论】:

    【解决方案3】:

    [NSDictionary dictionary][NSArray array]等方法,返回autoreleased对象。这意味着您没有这些对象的所有权,并且您无需担心内存管理。
    当您使用 newalloc 时,您需要在使用完毕后释放这些对象。

    当您不使用 ARC 时,这种区别很重要。

    【讨论】:

    • new 不返回 autoreleaed 对象。
    • @LeoNatan 我知道,我从来没有说过。
    • “所有这些方法”的措辞非常很糟糕。
    • @LeoNatan 已更正,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2012-04-15
    • 1970-01-01
    相关资源
    最近更新 更多