繁体   English   中英

Objective-C:自动释放混乱

[英]Objective-C: autorelease confusion

假设我有一个DoStuff类,该类​​有两个方法,像这样

- (NSMutableDictionary* returnToCaller) methodOne : (NSString* ) myString {

    NSMutableDictionary* bundleOfJoy = [[NSMutableDictionary alloc] init]; 

    if (myString) { 
       bundleOfJoy = [self methodTwo];
    }

    return bundleOfJoy; 

} 

- (NSMutableDictionary* returnToMethodOne) methodTwo {

    NSMutableDictionary* anotherDictionary = [[NSMutableDictionary alloc] init]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"];

    return anotherDictionary;  
}

好的,请耐心等待,因为我的记忆管理功能有点薄弱。 我不能释放返回后手动创建的两个字典,因为不会调用release命令。 在返回之前我无法做到这一点,或者我没有传递任何值。 我的理解是使用自动释放池来解决此问题的方法。

pool = [[NSAutoreleasePool alloc] init];

然后像这样初始化我的对象

NSMutableDictionary* anotherDictionary = [[[NSMutableDictionary alloc] init] autorelease];

然后打电话

[pool drain];

所以,如果那是正确的,我应该在哪里初始化池? 在awakeFromNib中吗? 我在哪里称呼[水池排水口]?

如果这是不正确的,有人可以理顺我(但请缓慢输入):D

谢谢

每个线程中都有一个自动的NSAutoreleasePool,不必创建一个自动线程,而是要创建一个新线程。

使用[pool release]; 除非有内存泄漏,否则不要使用[poolrain]。

对于您的代码,释放分配的对象是方法的责任,因此添加

 return [bundleOfJoy autorelease]; 
 return [anotherDictionary autorelease];

系统为您维护一个自动释放池。 它是在程序启动之前创建的,并在事件循环得到控制时定期清除。 在大多数情况下,您不需要自己的自动释放池:只需在返回对象之前调用autorelease ,就可以了。

PS:如果您想了解确实需要自己的自动释放池的情况, Apple可以为您提供一个不错的指南

在大多数情况下,将为您设置自动释放池。 除非您在不使用GCD的情况下在单独的线程中运行代码,否则不需要分配和消耗池。 即使您确实在该方法中放入了自动释放池,该对象也会过早地自动释放,因为您将不得不消耗相同的方法。 据说可以得到一个自动释放的对象,您可以使用便捷构造函数或将autorelease添加到您的alloc/init

- (NSMutableDictionary* /*returnToMethodOne*/) methodTwo {
    //Convenience constructor
    NSMutableDictionary* anotherDictionary = [NSMutableDictionary dictionary];
    //or    
    //NSMutableDictionary* anotherDictionary = [[[NSMutableDictionary alloc] init] autorelease]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"];

    return anotherDictionary; 
}

而且您通常不会自己创建和消耗池,而是由框架为您完成的,因此您只需自动释放要稍后释放的对象即可。

当然,这种方式无法控制时间,因此,如果在程序的某些部分中创建了许多临时自动释放的对象,则可以将以下代码包装在池创建和消耗中:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
... create objects...
[pool drain];

但是正如我所说,这只是特殊情况的一种选择。

最好的解决方案是使用ARC。 然后,您将不必再为此担心。 :)

即使那样,您仍需要了解ARC为您做了什么。 我的iOS编程书中的讨论同样适用于Mac OS X:

http://www.apeth.com/iOSBook/ch12.html#_memory_management

您需要autorelease返回的对象。 它们将存在,供您的调用代码使用,但将在稍后的任意时间释放。

- (NSMutableDictionary* returnToMethodOne) methodTwo {
    NSMutableDictionary* anotherDictionary = [[NSMutableDictionary alloc] init]; 
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"];

    return [anotherDictionary autorelease]; 
}

几乎不需要使用自动释放池,除非您需要在运行生成大量对象的循环时确保低内存使用。

实现此功能的另一种方法是创建一个不需要释放内存的自动释放对象(使用便捷构造函数)。 例如:

- (NSMutableDictionary* returnToMethodOne) methodTwo {
    NSMutableDictionary* anotherDictionary = [NSMutableDictionary dictionary]; // Creates an autoreleased NSMutableDictionary object.
    [anotherDictionary setObject: @"hardcodedstring" forKey: @"theKey"];

    return anotherDictionary; // No `autorelease` call because it's not our memory to manage.
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM