Iphone 类方法中是否有自动释放池?
我有一个生成UIImage的类方法,如下所示: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*)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
您可以使用retaincount检查NSObject派生项的当前保留计数UIImage保留图像数据,因此,如果您确实在泄漏内存,您应该检查是否正在释放返回的img 数据变量retain count如下所示:
- 分配:1
- 创建包含以下数据的图像:2
- [数据发布]:1
您可以使用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在所有情况下的工作方式都是一样的 我知道我