现在的位置: 首页 > 综合 > 正文

iOS中正确处理dealloc方法

2014年08月29日 ⁄ 综合 ⁄ 共 1853字 ⁄ 字号 评论关闭

当我们继承类的时候,子类实例在构造的时候顺序是先高用父类的构造方法,再调用子类的构造方法。在c/c++是如此,在objc中也是如此,在iOS开发中,我们会看到这样的代码:

- (void)init
{
    self = [super init];
    if (self)
    {
        //init
    }

    return self;
}

看到没,初始化的时候都是先调用父类的初始化方法,为什么呢,因为父类更老,当然是先出生了。大笑,同样的情况可以在viewDidLoad中看到。

而销毁的时候则是相反的顺序,先销毁子类里分配的空间,再销毁父类的。如:

- (void)dealloc {
    [companion release];
    free(myBigBlockOfMemory);
    [super dealloc];
}

为什么会是这个顺序呢?因为长江后浪推前浪,子类是继承了父类的优点,发挥了自己长外, 敌人要想消灭对方,当然是先灭最强的,都说树大招风,就是这个道理。在销毁的时候如果不按这个顺序,有时候可能会crash。如在子类中应用了:

[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

如果dealloc写这成这样就会在removeFromRunLoop的时候crash:

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

如果写成这样就ok了:

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

在xCode version:4.2.1及以前版本中开发iOS的时候,如果将super dealloc写在子类dealloc中前面的时候是不会出错的,但在xCode version4.3.2中,它会有自动检测super dealloc的功能,如果写在前面,则会crash.

苹果官网也推荐这样写,请参看:https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/dealloc 中的特别注意事项中

Special Considerations
When garbage collection is enabled, the garbage collector sends finalize to the receiver instead of dealloc, and this method is a no-op.

If you are using manual reference counting, subclasses must implement their own versions of dealloc to allow the release of any additional memory consumed by the object—such as dynamically allocated storage for data or object instance variables owned by the
deallocated object. After performing the class-specific deallocation, the subclass method should incorporate superclass versions of dealloc through a message to super

抱歉!评论已关闭.