iOS - 我很困惑这里如何处理内存?

时间:2011-09-27 13:04:03

标签: iphone objective-c ios ipad ios4

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 - 让我们说(文件路径无效),这个内存将被泄露为

  

myObject的/ yourObject

即使在 init 之前分配

也会设置为nil。

我已经以这种方式看到了许多扩展类/接口的实现。我很困惑这里如何处理内存?任何人都可以就此分享观点吗?

3 个答案:

答案 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;
}