释放可能尚未创建的对象

时间:2011-08-16 08:59:11

标签: objective-c memory-management

在我阅读的大多数教程中,都有使用自定义init方法的类的示例。

例如

@implementation MyPerson

-(id) initWithDefaultName {
self = [super init];
if (self) {
NSString *name = [[NSString alloc] initWithString:@"John Doe"];
}
return self;
}

现在,我知道我应该把它配对

-(void) dealloc
{
[name release];
[super dealloc];
}

我不明白的是,如果我拨打[MyPerson init]后跟[MyPerson release]

,这就不会崩溃的原因

编辑:阅读下面的评论,我意识到上面的示例代码并不完全正确。我得到的是我的自定义initWithName方法分配并初始化一个在调用标准init方法时不存在的对象。所以我的dealloc方法包含释放它的代码,但是即使从未创建名称对象,这仍然有效吗?

4 个答案:

答案 0 :(得分:5)

实例变量的默认值为nil。向nil发送邮件无效。

答案 1 :(得分:2)

如果您这样做,请使用Java:

Foo foo = null;
int bar foo.getBar();

你会得到一个空指针异常。在Objective-C中,向nil发送消息是完全可以的,它被视为无操作,没有任何操作。

小警告;如果返回类型的大小符合ABI的默认返回约定,则返回值将等于nil的数据类型表示形式。所以这一切都会起作用并产生预期的回报值:

Foo* foo = nil;
id a = [foo objectValue];    // a will be nil
BOOL b = [foo boolValue];    // b will be NO
int c = [foo intValue];      // c will be 0
float d = [foo floatValue];  // d will be 0.0f

这可以为您的代码带来很大好处,想象一下这个例子:

if ([myString length] > 0) {
    // Do stuff here
}

通过这种方式,myString是空字符串还是仅nil并不重要。在这两种情况下,询问长度将返回0。使许多操作更容易编写,因为nil值很少被考虑在内。

仅对于返回类型(例如不适合返回寄存器的结构),您将无法获得定义的返回值:

Foo* foo = nil;
CGRect a = [foo rectValue];  // content of a will be undefined.

答案 2 :(得分:1)

您可以安全地将发布发​​送到零。但请注意,在init中分配名称时应该保留名称。

答案 3 :(得分:1)

您可以向nil对象发送任何内容,这样就可以了。

这就是为什么大多数教程还会在nil方法中将每个属性设置回viewDidUnload