如果我在向NSOperation
发送-init
之前发布了segmentation fault
的实例,我会得到NSObject
。
我认为这是有效代码的原因:
implementation of NSNumber
中执行此操作,因此相当确定这也是Apple的代码。 (至少是。)-init
s -release
没有做任何事情,因此属于NSObject
的{{1}}应该在此之前工作。// gcc -o test -L/System/Library/Frameworks -framework Foundation test.m
#import <Foundation/Foundation.h>
int main(int argc, char *argv[]) {
NSOperation *theOperation = [NSOperation alloc];
[theOperation release];
}
答案 0 :(得分:7)
将除init
以外的任何消息发送到尚未初始化的对象不是有效代码AFAIK。调用超类初始化程序,然后释放,我打赌它不会崩溃(虽然有一个类的初始化程序返回一个完全不相关的类打击我作为doubleplusungood)。
答案 1 :(得分:2)
该代码无效。
将您的-init重写为:
- (id) init
{
if (self = [super init]) {
[self release];
NSNumber *number = [[NSNumber alloc] initWithInteger:6];
return number;
}
return self;
}
当然,代码仍然是无稽之谈,但它不会崩溃。
在发送消息之前,您必须始终呼叫超级初始化程序。而且你必须始终使用上面显示的模式。
答案 2 :(得分:1)
我认为你需要在调用release之前初始化你的超类,但根据Apple的文档中的this example,情况并非如此。
所以它可能是一个错误,但肯定不是一个重要的错误。
答案 3 :(得分:1)
我的前期分析并不正确。
但是,我想指出这个问题可能发生在不同的类中。它实际上取决于你是哪个类继承。子类化NSObject没有问题,但子类化NSOperation,NSOperationQueue和NSThread是一个问题,例如。
之所以发生这种情况是因为就像你可能会这样,你子类的类可能会在他们的-init
方法中分配内容。这也是你设置nil
尚未分配的变量的地方(稍后可能在你的代码中这样做)。
因此,通过在没有先前-release
的情况下调用-init
,您可能会导致其中一个父类释放它尚未分配的对象。他们无法检查他们的对象是否为nil
,因为它甚至没有机会初始化它所需的每个对象/值。
这也可能是为什么在没有init的情况下发布NSOperation在10.5上工作并且在10.6上不起作用的原因。 10.6实现已经被重写为使用块和Grand Central Dispatch,因此,他们的init
和dealloc
方法可能已经发生了很大的变化,在这段代码上创建了不同的行为。