Mac OS X 10.6中的NSOperation是否有错误?

时间:2009-10-04 17:12:34

标签: objective-c nsoperation foundation

如果我在向NSOperation发送-init之前发布了segmentation fault的实例,我会得到NSObject

我认为这是有效代码的原因:

  • Apple在its documentation中执行此操作。
  • Gnustep在其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];
}
  • 您怎么看?这是一个错误吗?
  • 你能告诉我一个具有相同行为的另一个类的例子吗?
  • 知道为什么会这样吗?

4 个答案:

答案 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,因此,他们的initdealloc方法可能已经发生了很大的变化,在这段代码上创建了不同的行为。