Iphone 类方法中是否有自动释放池?

Iphone 类方法中是否有自动释放池?,iphone,memory-management,Iphone,Memory Management,我有一个生成UIImage的类方法,如下所示: + (UIImage*)imageWithFileName:(NSString*)imgFile { UIImage *img = nil; NSBundle *appBundle = [NSBundle mainBundle]; NSString *resourcePath = [appBundle pathForResource:imgFile ofType:nil]; if (resourcePath !=

我有一个生成UIImage的类方法,如下所示:

+ (UIImage*)imageWithFileName:(NSString*)imgFile {
    UIImage *img = nil;

    NSBundle *appBundle = [NSBundle mainBundle];
    NSString *resourcePath = [appBundle pathForResource:imgFile ofType:nil];

    if (resourcePath != nil) {
        NSURL *imageURL = [NSURL fileURLWithPath:resourcePath];
        NSData *data = [[NSData alloc] initWithContentsOfURL:imageURL];

        img = [UIImage imageWithData:data]; // should be autoreleased!!

        [data release];
    }

    return img;
}

但是,当我使用它时,图像数据永远不会被释放。这肯定是内存错误,尽管我没有违反我所知道的任何内存管理规则。我的猜测是,因为这是一个从实例方法调用的类方法,所以没有活动的自动释放池,或者只有当我退出应用程序时,它才会被耗尽。这是对的吗?

UIImage保留图像数据,因此,如果您确实在泄漏内存,您应该检查是否正在释放返回的img

数据变量retain count如下所示:

  • 分配:1
  • 创建包含以下数据的图像:2
  • [数据发布]:1
因此,除非img被释放,否则它所提供的数据不会被释放(这是有意义的,因为图像需要数据)


您可以使用retaincount检查NSObject派生项的当前保留计数

UIImage保留图像数据,因此,如果您确实在泄漏内存,您应该检查是否正在释放返回的img

数据变量retain count如下所示:

  • 分配:1
  • 创建包含以下数据的图像:2
  • [数据发布]:1
因此,除非img被释放,否则它所提供的数据不会被释放(这是有意义的,因为图像需要数据)


您可以使用retaincount检查NSObject派生项的当前保留计数

一旦将数据传递到
img
,它就不在您的掌握之中了。UIImage可能在其内部实现中保留原始数据。但这并不重要。从您的角度来看,您已经适当地发布了
数据
,完全取决于
img
来确定它是否希望保留它

您是否明确保留返回的UIImage?或者把它传给另一个班级?例如,如果将其放置到UIView中,视图将保留
img
,直到不再需要它


关于你明确的问题:有一个主运行循环自动释放池。它通常在每次事件循环后都会耗尽。

一旦您将数据传递到
img
,它就不在您的掌控之中了。UIImage可能在其内部实现中保留原始数据。但这并不重要。从您的角度来看,您已经适当地发布了
数据
,完全取决于
img
来确定它是否希望保留它

您是否明确保留返回的UIImage?或者把它传给另一个班级?例如,如果将其放置到UIView中,视图将保留
img
,直到不再需要它


关于你明确的问题:有一个主运行循环自动释放池。它通常在每次事件循环后都会被耗尽。

经过一些测试,我发现问题确实与自动释放池有关。如果在实例方法中使用完全相同的代码,则绝对没有问题

但只要我在类方法中使用它,自动删除的UIImage对象就永远不会被释放。无论autorelease池堆栈的autorelease池是类内最顶级的方法,它都与实例内的方法严重不同。我很确定现在类方法接收到的是一个非常低级别的自动释放池,只有在应用程序退出时才会被耗尽或释放

所以在类方法中做自动释放的东西时要小心。当然,在本地创建ARP毫无帮助,因为您可能需要(就像我在本例中所做的那样)返回一个自动释放的对象

我将把我的代码改为+newImageWithFileName:,并返回一个未自动释放的对象,因此接收者肯定要释放它,或者可能会向该对象发送-autorelease


我希望有人能提供关于这个问题的更多细节。

经过一些测试,我发现这个问题确实与自动释放池有关。如果在实例方法中使用完全相同的代码,则绝对没有问题

但只要我在类方法中使用它,自动删除的UIImage对象就永远不会被释放。无论autorelease池堆栈的autorelease池是类内最顶级的方法,它都与实例内的方法严重不同。我很确定现在类方法接收到的是一个非常低级别的自动释放池,只有在应用程序退出时才会被耗尽或释放

所以在类方法中做自动释放的东西时要小心。当然,在本地创建ARP毫无帮助,因为您可能需要(就像我在本例中所做的那样)返回一个自动释放的对象

我将把我的代码改为+newImageWithFileName:,并返回一个未自动释放的对象,因此接收者肯定要释放它,或者可能会向该对象发送-autorelease


我希望有人能提供更多关于这个问题的细节。

我想真正的问题是,你如何衡量内存没有被释放

自动释放池都与您所在的线程和运行循环相关,因为当调用返回到主运行循环时,它们会释放内存。无论您是调用类方法还是实例方法,甚至是调用C函数,autorelease在所有情况下的工作方式都是一样的


我知道在您的测试中您发现了差异,但简单地说,如果您看到差异,这是出于其他原因-因为自动释放在整个系统中的工作方式都是一样的,只要您处于相同的运行循环中,就可以释放内存。

我认为真正的问题是,您如何衡量内存是否未释放

自动释放池都与您所在的线程和运行循环相关,因为当调用返回到主运行循环时,它们会释放内存。无论您是调用类方法还是实例方法,甚至是调用C函数,autorelease在所有情况下的工作方式都是一样的

我知道我