谈论的是Objective-c中的类和对象。 我无法理解[super dealloc]的概念。 我们有一些类说myClass,它继承自NSObject。它有一些方法,并从父类继承其他方法。所以我们这里也有dealloc方法。为什么我不能只使用[myInstance dealloc]? 我是否认为我们调用父类方法来杀死类的实例?为什么这么复杂?
这不是关于[myInstance发布]的讨论我对这个概念没问题。
答案 0 :(得分:8)
已经有一些很好的答案,但我会更直接地回答这些问题:
为什么我们写[super dealloc]
?
我们写它是因为那是实际销毁实例的东西。否则永远不会释放内存。
为什么我们不写[self dealloc]
?
我们无法写出来,因为您应该明确调用dealloc
的唯一地方是dealloc
方法。在[self dealloc]
内执行dealloc
只会使方法调用本身,然后调用自身,调用自身,调用自身,并调用自身......。
为什么我们不写[myInstance dealloc]
?
我认为myInstance
只是另一个指向对象的方法中的变量的占位符,而您在问我们为什么不通过该变量调用dealloc
。这是因为你不知道对象何时应该dealloc 。 retain
和release
的重点是让您不必跟踪对象何时被销毁。您只需正确保留和释放对象,并且当release
被调用足够多次,表明该对象没有更多的所有者想要保留对它的引用时,它将自己调用dealloc
。
答案 1 :(得分:7)
您的问题实际上是一个更通用的问题,可以从dealloc
问题中删除。
覆盖方法以及何时应致电super
。
有时,当您进行子类化时,您将覆盖现有方法。有时你想利用那个方便的时间来执行一些行为,有时你想阻止父母做某事并改变行为。
- (void)methodOne {
// don't let silly parent class do method one stuff
// do my stuff …
}
- (void)methodTwo {
// let parent perform his behavior first
[super methodTwo];
// do my stuff …
}
- (void)methodThree {
// do my stuff …
// let parent do his stuff after I have
[super methodThree];
}
- (void)methodFour {
// it's not common, but you might want to split your stuff with a call to
// super - this usually involves knowledge of what super is up to
// do some stuff …
[super methodFour];
// do my stuff …
}
许多方法/类的文档(请参阅UIView和NSManagedObject)可能会说明您是否可以或不应该覆盖方法。好的文档会告诉你何时应该调用super。
在调用[super dealloc]
时,您应该在释放资源后最后调用它。 (因为您可能引用的其他内存可能会被您的父类释放)。
另一个super
的调用是在init方法中。如果你实现了一个init方法,你应该覆盖父方的“指定初始化方法”,你应该从你的方法中调用super。
@implementation CustomViewController
- (id)init {
return [super initWithNibName:@"CustomView" bundle:nil];
}
- (id)initWithNibName:(NSString *)name bundle:(NSBundle *)bundle {
return [self init];
}
//…
此常见模式可防止任何人使用不正确的nib文件加载您的类。 (这可能是也可能不是,这是另一个问题。)
如果碰巧有其他初始化器,根据定义,它们应该调用它们的指定初始化器。因此,如果UIView要添加initWithNibName:
方法,它可能会调用[self initWithNibName:name bundle:nil]
,然后将其“捕获”并重定向到您想要的初始化程序。
答案 2 :(得分:5)
调用-dealloc
时,合同是它在类层次结构中向上运行,以确保正确处理每个父类使用的内存。 [self dealloc]
会再次调用您的方法并为您提供无限循环。 [super dealloc]
删除你的超类设置的任何内容 - 如果那个超类是NSObject
,它还会释放对象占用的内存。
答案 3 :(得分:3)
你这样做:
@interface MyClass : SuperClass
@end
@implementation MyClass
- (void)dealloc
{
// Release stuff allocated in MyClass
[super dealloc];
}
@end
那是什么意思?假设你有一个MyClass
的实例,它已经被释放/自动释放,直到它的保留计数降到0. Objective-C现在想要销毁实例。为了清理内容,Objective-C调用dealloc
方法。
现在,被调用的是MyClass中定义的dealloc
。但是你从其他一些类派生了这个类。这意味着这个超类也可能有清理的东西。所以你必须调用[super dealloc];
,这意味着:按照SuperClass 中的定义执行dealloc
。
类似的概念适用于您的init
或initFoo
方法:在其中您执行类似self = [super init];
的操作,以便超类可以进行初始化。
此外,您不应该直接致电dealloc
!只有在清理对象的时候才能通过Objective-C调用它。
BTW,self
表示:我的对象的当前实例,而super
表示:我的对象的当前实例,但使用定义的方法由超类。
答案 4 :(得分:1)
简而言之,它是初始化程序的补充。概念是初始化从inheiritance层次结构的顶部传播到底部以首先初始化所有父字段,并且释放从底部传播到顶部以首先清理所有子字段。在init
方法中,您始终先致电[super init]
,然后在dealloc
中始终致电[super dealloc]
。有关[super dealloc]
的更多信息,请查看this question
答案 5 :(得分:0)
不,你是对的。
父类(在您的示例中为NSObject)必须运行自己的指令。
这就是为什么在您编写发布说明之后,将dealloc
发送到超类以完成此过程。
答案 6 :(得分:0)
在[self dealloc]
中使用-dealloc
会导致无限递归。 -dealloc
方法会继续调用自己。您无法在[object dealloc]
中使用-dealloc
,因为除了self
之外,您不会,也不应该指向自己。你是正确的NSObject
需要自己清理。一个班级创造的所有东西都负责清理。此外,[super dealloc]
必须是-dealloc
的最后一行。否则,您可能在该点之后没有分配的对象。