Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 为什么我必须最后一个而不是第一个叫super-dealloc?_Iphone_Cocoa Touch_Memory Management_Uikit - Fatal编程技术网

Iphone 为什么我必须最后一个而不是第一个叫super-dealloc?

Iphone 为什么我必须最后一个而不是第一个叫super-dealloc?,iphone,cocoa-touch,memory-management,uikit,Iphone,Cocoa Touch,Memory Management,Uikit,正确的例子: - (void)dealloc { [viewController release]; [window release]; [super dealloc]; } 错误的例子: - (void)dealloc { [super dealloc]; [viewController release]; [window release]; } 尽管在大多数其他情况下,当重写一个方法时,我会首先调用super的方法实现,但在这种情况下,苹果

正确的例子:

- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}
错误的例子:

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

尽管在大多数其他情况下,当重写一个方法时,我会首先调用super的方法实现,但在这种情况下,苹果最终总是调用[super dealloc]。为什么?

我对iPhone的编程一无所知,但我认为,出于同样的原因,析构函数需要按相反的顺序调用。在调用超类之前,您需要确保清除所有的“垃圾”。如果你换一种方式做,事情会变得一团糟。例如,如果析构函数需要访问超级析构函数已释放的内存:

class X {
    private Map foo;

    function __construct() {
        foo = new Map();
    }

    function __destruct() {
        foo.free;
    }
}

class Y extends X {
    function __construct() {
        super.__construct();
        map.put("foo", 42);
    }

    function __destruct() {
        super.__destruct();
        if (map.containsKey("foo")) {    // boooooooooom!
            doSomething();
        }
    }
}

您可能不会在代码中遇到这个问题,因为“您知道自己在做什么”,但不做这些事情是更安全、更全面的做法。

这只是一个指导原则。您可以在
[super dealoc]
之后调用其他指令。但是,您不能再访问超类的变量了,因为当您调用
[super dealoc]
时,它们会被释放。在最后一行调用超类总是安全的


另外,如果KVO和依赖(触发)键依赖于已发布的成员变量,则它们可能会产生副作用

[super dealoc]正在释放对象使用的内存,包括指向viewController和window的指针。在释放变量后引用它们充其量是危险的


请参阅。

实际上,您在最后几乎有了
[super dealoc]
,因为它释放了超类的变量,并且它们无法再被访问


一个例外是,如果UITableViewController的子类使用另一个类作为其表视图委托。在这种情况下,您必须在
[super dealoc]
之后释放表视图委托,因为表视图引用了表视图委托,必须首先释放表视图。

以下是实际示例,其中[super dealoc]必须是最后一个,否则调用removeFromRunLoop将导致崩溃。我不确定NSOutputStream的removeFromRunLoop中发生了什么,但在本例中它似乎访问了“self”

设置:

[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
解除锁定:

- (void)dealloc {
    if (outputStream) {
        [outputStream close];
        [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
        [outputStream release];
        outputStream = nil;
    }
    delegate = nil;
    [super dealloc]; // must be last!
}

[到最后一篇文章]引用委托的tableView不负责释放自己的委托吗?我认为它在设置时会保留它(这样你就可以释放或自动释放它),并且它会自行处理吗


至于OP问题,如果我在构造,我总是先调用super,如果我在破坏,我总是调用super last。我认为它是“我想让super构建它想要的东西,这样我就可以在此基础上构建,我想super在我自己清理完后最后拆掉。”但实际上我使用的所有调用都在构建,除了dealloc,所以这就是为什么你总是在我的dealloc代码中最后看到它的原因。

我的猜测是因为它回答了这个问题,至少部分。另一方面,否决票通常意味着答案毫无用处或完全错误。如果是错误的,我很想知道为什么,这样我就可以从错误中吸取教训。还是你只是在争论?我没有投反对票;这是个好答案。然而,否决票是公平的,因为这是一个猜测,不是针对Cocoa框架的。@n3rd,我同意@adam,这不是关于Cocoa/obj cIf的具体答案。正如我所假设的,问题确实是一个一般性的问题,这是完全无关的。如果你想知道为什么调用“null对象”是个坏主意,那么如果你谈论java、PHP、C++或者JavaScript,那就没关系了。你能不能详细说明一下你的异常?这听起来有点不对。@Mark:我也觉得不对。通常情况下,为了避免保留循环,您甚至不会首先保留委托。使用ARC,您根本不必调用
[super dealloc]
,这样做时会产生编译器错误。