【问题标题】:Idiomatic short lifespan local objects akin to RAII类似于 RAII 的惯用短寿命本地对象
【发布时间】:2011-10-13 11:51:23
【问题描述】:

我偶然发现了这个 Objective-C 的片段:

NSNumber *theBalance = 
    [[[NSNumberFormatter alloc] init]
     numberFromString: [textField text]];

这似乎泄露了NSNumberFormatter。在 C++ 中,我会做以下两件事之一:

  1. NSNumberFormatter 使用auto(即堆栈)存储
  2. 使用 RAII(例如shared_ptr)来管理NSNumberFormatter 的生命周期

在 Objective-C 中,这些选项似乎都不可能。我在堆栈上试过:

NSNumberFormatter fmt;

但这不能编译。据我所知,Objective-C 中没有直接等效的 RAII。作为一个主要是 C++ 的程序员,我可能从错误的角度看待这个问题,所以:

  1. 在一般情况下,处理像NSNumberFormatter 这样的对象生命周期的正确、惯用(现代)Objective-C 方法是什么?我真的必须自己明确地这样做吗?
  2. 在具体情况下,有没有更好的办法解决实际问题?

【问题讨论】:

    标签: iphone objective-c ios memory-management raii


    【解决方案1】:

    NSStringNSArray 等大多数类都有方便的构造函数,如[NSString string][NSArray array],它们返回自动释放的对象。 NSNumberFormatter 没有任何便利的构造函数。所以,你可以发送autorelease 消息让它在自动释放池耗尽时自动释放。

    NSNumber *theBalance = [[[[NSNumberFormatter alloc] init] autorelease]
                           numberFromString: [textField text]];
    

    如果你想保留(拥有)对象的引用,你可以省略autorelease,等你完成后释放它。就这样吧,

    NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
    NSNumber *theBalance = [numberFormatter numberFromString: [textField text]];
    
    // Later... somewhere in your code...
    [numberFormatter release];
    

    我知道上面不是详细的解释。我建议你read this post,希望你能对内存管理有一些清晰的认识!

    【讨论】:

    • autorelease 似乎是我所缺少的信息,它结合了像 C++ 程序员一样的思维方式,让我有点离题了。 autorelease 只是说“在未来调用发布的某个时间点”,其中“某个点”保证在当前语句(序列点?)结束之后,对吧?
    • @awoodland:是的,就是这样。在 Cocoa 中,我们经常谈到所有权,我们说 releaseautorelease 我们放弃了对象的所有权:立即使用 release,稍后使用 autorelease。通常,自动释放的对象在每次运行循环迭代时被释放。您可能有兴趣阅读 Mike Ash 的 Let's build NSAutoreleasePool 以了解实际情况。
    • @awoodland,这里的“某个点”并不意味着当前语句的结束。这意味着只要当前的自动释放池被销毁,对象就会被释放。它保证在当前方法(您创建/自动释放对象的位置)执行结束之前不会释放对象。只有当您尝试在创建/自动释放对象的方法之外访问对象时,您才会遇到问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-25
    相关资源
    最近更新 更多