代码之家  ›  专栏  ›  技术社区  ›  Garrett

这两个init方法有什么区别?

  •  2
  • Garrett  · 技术社区  · 15 年前

    据我所知,第一个在完成后必须释放,第二个不释放。为什么要在第二个初始化之后使用第一个初始化?

    NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] initWithObjectsAndKeys:@"title", @"text", nil];
    

    NSMutableDictionary *dictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"title", @"text", nil];
    
    5 回复  |  直到 15 年前
        1
  •  2
  •   h4xxr    15 年前

    正如其他人所说,在某种意义上,您的两个示例之间没有区别,只是第一个实例返回一个保留的对象,在您明确释放它之前,它不会被释放;第二个实例是一个自动释放的对象,它将在下一个运行循环开始时自动释放,除非您明确地保留它。然后。

    然而,问题的关键部分是:

    你为什么要用第一个 第二次初始化?

    通常认为的方法(由Apple文档支持)是使用自动释放的对象 绝对罚款 在大多数情况下。我不同意彼得刘易斯这里关于iPhone是如此“动力不足”,你需要避免自动释放的对象。在大多数应用程序中,提供自动释放对象的额外电话开销是微乎其微的。因此,您可以在代码中自由地使用自动释放的对象,如果需要挂起它们,只需显式地保留它们。

    但是,在哪里 与众不同之处在于 紧环 . 如果您正在运行一个while循环,例如执行1000次,并且您正在该循环中创建以后不需要的对象,那么您应该显式创建新的非自动释放对象并显式释放它们。这是因为自动释放池在紧密循环中不会(默认情况下)为空。创建大量自动释放的对象很可能会开始触及设备内存的限制。

    总而言之,大多数情况下使用2),但如果您打算一次创建和丢弃大量对象,则使用1)。

    希望有所帮助

        2
  •  2
  •   Jason    15 年前

    您是正确的;对于第一个版本,您需要显式地释放对象。如果要将第一个版本分配给类中的实例变量,则该版本非常有用;即,它是一个字典,将超出当前的UI事件(后一个对象是自动释放的,稍后在程序中不可用)。

    例如:

    -(id)init
    {
        if (self = [super init])
        {
            myDict = [[NSDictionary alloc] init ...];
        }
        return self;
    }
    
    -(void)dealloc
    {
        [myDict release];
        [super dealloc];
    }
    
        3
  •  0
  •   jbrennan    15 年前

    第一个init方法是 instance 方法(在返回的实例上工作 [NSMutableDictionary alloc] )并且不是自动释放的对象,保留计数为1。

    第二个是 class 方法,并返回一个自动释放的对象(基本上没有保留计数)。

        4
  •  0
  •   James    15 年前

    第二个是由nsmutabledictionary类自动发布的,第一个类是处理自己的内存管理。

        5
  •  0
  •   Peter N Lewis    15 年前

    阅读 memory management rules . 9小段,你可以在一分钟内读完。他们清楚地解释了两者的区别。

    至于为什么要使用其中一个,这取决于平台。

    在电量不足且内存不足的iPhone上,您通常更喜欢前者,除非您将被迫使用Autorelease(例如,如果要从名称不以__alloc_157;或_156;new_157;或包含__copy_157;开头的方法返回)。如果要自动释放,请使用第二个窗体。否则,使用第一个表单并在方法中显式地释放它。

    在Mac上,它有足够的能力和内存使自动释放池成为一个微不足道的细节(除了最可悲的情况),您可以对任何情况使用第二种形式。通常,如果您打算保留它,您会将它分配给一个复制/保留属性,这样您就不需要保留它。例外情况发生在init方法中,您不能使用setter,或者在手动实现的setter中,因此需要自己分配给ivar。在这些情况下,您经常使用前者。

    但所有这些都只是样式/过早的优化(在这种情况下不一定是坏的,因为in是一种低级别的噪声优化,配置文件不会检测到这种优化,这通常只会使应用程序慢一点)。重要的是阅读规则并遵循它们所说的内容,如果你这样做,你可以使用任意一种形式。