我应该在非指定初始化程序失败后自动发布吗?

时间:2010-09-21 01:18:05

标签: objective-c

说我有以下课程:

@interface Frob : NSObject {
    NSData *data;
}
- (id)initWithData:(NSData *)inData;
@end

@implementation Frob
- (id)initWithData:(NSData *)inData 
{
   if ((self = [super init])) {
       data = [inData retain];
   }
   return self;
}
- (void)dealloc
{
    [data release];
    [super dealloc];
}
@end

我现在想要添加一个方便的方法来读取URL。所以我写了一些看起来像这样的东西:

- (id)initWithContentsOfURL:(NSURL *)url
{
    NSError *error = nil;
    NSData *data = [NSData dataWithContentsOfURL:URL options:0 error:&error];
    if (!data) {
        NSLog(@"Frob couldn't read data, error: %@", error);
        [self autorelease]; // !!!
        return nil;
    }
    return [self initWithData:data];
}

!!!行为我举起了一个红旗:我(有效地)在-release'的对象上调用+alloc,但是超级类-init从未实际调用。这样安全吗?

提出同一问题的另一种方式:从概念上讲,-release+alloc相反吗?或+alloc-[<root class> init]

非常感谢澄清。

2 个答案:

答案 0 :(得分:2)

  

提出同一问题的另一种方式:从概念上讲,是 - 释放与+ alloc相反的方式吗?或+ alloc和 - [init]?

不,它在概念上并非相反。但是,从概念上讲,alloc会执行一个保留,其中 与发布相反,并且在初始化失败时释放您的保留。

请注意,由于init中的释放,将调用dealloc,因此dealloc需要使用部分(或根本不是)初始化对象。在您的情况下,当调用dealloc时,您的实例变量都将为nil / NULL / 0 / false。

答案 1 :(得分:1)

这是完全可以的,因为在你返回nil后你的对象将没有句柄。如果有的话你应该做一个释放而不是自动释放。 [nil release]是一个无操作的事实,你大部分都被覆盖,因为超类没有被初始化,其中没有任何东西是非零的。