UIImage API参考文档: -
initWithContentsOfFile:
使用指定文件的内容初始化并返回图像对象。
- (id)initWithContentsOfFile:(NSString *)path
参数
的 路径
文件的路径。此路径应包含标识图像数据类型的文件扩展名
返回值
如果方法无法找到文件或从其内容初始化图像,则初始化的 UIImage对象或 nil 。
考虑到这种情况,假设我有一个类,它可以是任何类的扩展。以UIImage为例。
@interface myImage : UIImage
{
BOOL isDefaultSet;
}
-(id)initWithDefaultImage;
@end
@implementation myImage
-(id)initWithDefaultImage
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"];
idDefaultSet = YES;
return [self initWithContentsOfFile:path];
}
@end
//somewhere in other class:
NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"];
myImage *myObject = [[myImage alloc] initWithDefaultImage];
UIImage *yourObject = [[UIImage alloc] initWithContentsOfFile:path];
现在在这两种情况下,
“alloc”给出“retainCount + 1”
如果
由于某些问题initWithDefaultImage / initWithContentsOfFile
返回nil - 让我们说(文件路径无效),这个内存将被泄露为
即使在 init 之前分配,myObject的/ yourObject
也会设置为nil。
我已经以这种方式看到了许多扩展类/接口的实现。我很困惑这里如何处理内存?任何人都可以就此分享观点吗?
答案 0 :(得分:1)
通常相应的初始化程序会在返回self
之前释放nil
(新对象),如:
- (id)initWithFoo
{
self = [super init];
if (!self) return nil;
if (someInitializingFailed) {
[self release];
return nil;
}
return self;
}
您可以假设-[UIImage initWithContentsOfFile:]
正在实施相同的模式。因此,除非仪器确实告诉您泄漏,否则您不需要在您的情况下进行任何特殊处理。
答案 1 :(得分:1)
如果[super init]返回nil,则返回nil。所以控件从方法返回,if(someInitializingFailed)块永远不会被执行,内存将被泄漏,因为在调用“initWithFoo”之前已经执行了alloc
如果[super init]
返回nil
,则超级init
已经自行清理并释放alloc
分配的内存。
来自Handling Initialization Failure:
您应该仅在失败时调用自我发布方法。如果你从超类的初始化程序的调用中得到nil,那么你也不应该调用release。
答案 2 :(得分:0)
你是对的,有时人们会忘记处理这种泄漏。如果我们无法进行初始化,则需要释放分配的内存。
-(id)initWithDefaultImage
{
NSString *path = [[NSBundle mainBundle] pathForResource:@"someInvalidImage" ofType:@"png"];
if (path != nil)
{
self = [super initWithContentsOfFile:path];
}
else // cannot proceed with init
{
[self release];
self = nil;
}
return self;
}