【问题标题】:IPhone Objective C Memory AllocationiPhone Objective C 内存分配
【发布时间】:2012-08-15 21:06:17
【问题描述】:

我了解在使用 Alloc、new 或 copy 时,您拥有该对象并需要释放该对象。我明白,如果我保留一个对象,我需要释放它。

但是如果我在方法的末尾有以下语句:

return [[UIImage alloc] initWithContentsOfFile:path];

我拥有UIImage 对象,因为我分配了内存空间,但我不再引用它,因为它已返回给调用者。在我的dealloc() 方法中,我无法释放它,因为我没有参考。

所以我的问题是,这是否正确:

return [[[UIImage alloc] initWithContentsOfFile:path] autorelease];

我相信在这种情况下,调用者可以保留返回的对象,如果他们想获得所有权并最终需要释放自己。

感谢您的帮助。

【问题讨论】:

    标签: iphone objective-c memory memory-management alloc


    【解决方案1】:

    为什么要分配它?直接说:

    return [UIImage imageWithContentsOfFile:path];
    

    没有什么可以分配 - 没有什么可以释放。

    此外,这是使用 ARC 时的最佳选择,其中释放尝试会导致错误。

    【讨论】:

    • 我同意,UIImage 类有这样的方法,所以我不需要分配,UIImage 类将拥有该对象,因为它自己分配内存。我只是使用 UIImage 作为返回您分配的类的实例的示例。
    • 这个方法实际上返回一个自动释放的对象。
    • 如果返回一个先前分配的对象(当然是在当前方法中),说“return [object_bla_bla autorelease];”足以避免内存泄漏。同样关于“返回 [[[Bla_bla_Type alloc] initWith_bla_bla_or_whatever] autorelease];”
    【解决方案2】:

    但是,如果您使用 release,则字符串将在返回之前被释放(并且该方法将返回无效对象)。使用自动释放,您表示您想放弃所有权,但您允许方法的调用者在释放之前使用返回的字符串。

    【讨论】:

      【解决方案3】:

      两个答案都是正确的,但是你可能并不总是有一个方便的方法供你使用,所以我喜欢做的是你对自动释放所做的事情:

      - (MySomethingClass*)giveMeAFancyObject{
          MySomethingClass *obj = [[[MySomethingClass alloc] init] autorelease];
          obj.name = @"Something";
          // do some setting up maybe
          return obj;
      }
      

      【讨论】:

        【解决方案4】:

        自动释放的全部意义在于返回对象。

        - (id)bad {
            MyObj *obj = [[MyObj alloc] init];
            return obj;
        }
        

        此代码正确返回所有内容,但您(作为开发人员)必须确保稍后释放该对象。

        - (id)moreBad {
            MyObj *obj = [[MyObj alloc] init];
            return [obj release];
        }
        

        此代码按预期使用内存,在一个范围内平衡保留和释放,但返回的对象现在是垃圾(预计会崩溃)。

        - (id)good {
            MyObj *obj = [[MyObj alloc] init];
            return [obj autorelease];
        }
        

        此代码是“延迟发布”。 IE。您可以在调用方retain 对象,该对象将是安全的。如果您在范围内没有NSAutoreleasePool,它肯定会被破坏,但这是一种非常罕见的情况,而且您大多知道这种情况何时发生(最常见的情况是启动一个没有“默认”自动释放的新线程池)。

        因此,通常的做法是在一个范围中平衡保留(和类保留)和释放方法。下一个建议是始终使用 alloc-init-autoreleased 对象,如果您有内存问题(例如在循环中自动释放 lots 对象),则切换到不同的版本。下一个建议是切换到 ARC。

        【讨论】:

        • 支持彻底解释。
        【解决方案5】:

        你的假设是正确的。当你返回一个对象时,你应该将它作为一个自动释放对象传递。

        You use autorelease when you need to send a deferred release message—typically when returning an object from a method...

        【讨论】:

        • 谢谢,但是当使用 ARC 时,我想我不会使用 autorelease 并让编译器完成所有的内存管理。
        • 是的,ARC 会注意向所有对象发送释放。
        猜你喜欢
        • 2013-09-25
        • 1970-01-01
        • 2011-10-06
        • 2011-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 2011-01-11
        相关资源
        最近更新 更多