为什么我们使用[super dealloc]而不是[self dealloc]或[object dealloc]

Dvo*_*ole 3 cocoa cocoa-touch objective-c ios

谈论的是Objective-c中的类和对象.我无法理解[super dealloc]的概念.我们有一些类说myClass,它继承自NSObject.它有一些方法,并从父类继承其他方法.所以我们这里也有dealloc方法.为什么我不能只使用[myInstance dealloc]?我是否认为我们调用父类方法来杀死类的实例?为什么这么复杂?

这不是关于[myInstance发布]的讨论我对这个概念没问题.

Chu*_*uck 8

已经有了一些很好的答案,但我会更直接地回答这些问题:

  1. 我们为什么要写[super dealloc]

    我们写它是因为那是实际销毁实例的东西.否则永远不会释放内存.

  2. 我们为什么不写[self dealloc]

    我们不能这样写,因为你应该明确调用的唯一地方dealloc是在dealloc方法中.在[self dealloc]里面做dealloc只会使方法调用本身,然后调用自身,调用自身,调用自身,并调用自身....

  3. 我们为什么不写[myInstance dealloc]

    我假设myInstance在另一个指向对象的方法中,它只是一个变量的占位符,并且您在问我们为什么不只是调用dealloc该变量.这是因为你不知道对象何时应该dealloc.整点retainrelease是从不必跟踪当一个对象就可以被销毁的释放你.你只需要正确地保留和释放对象,并且当release被调用足够多次时,表明该对象没有更多想要保留对它的引用的所有者,它将dealloc自行调用.


bsh*_*ley 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 …
}
Run Code Online (Sandbox Code Playgroud)

许多方法/类的文档(请参阅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];
}

//…
Run Code Online (Sandbox Code Playgroud)

这种常见模式可以防止任何人使用不正确的nib文件加载您的类.(这可能是也可能不是,这是另一个问题.)

如果碰巧有其他初始化器,根据定义,它们应该调用它们的指定初始化器.因此,如果UIView要添加一个initWithNibName:方法,它可能会调用[self initWithNibName:name bundle:nil]哪个然后被"捕获"并重定向到您想要的初始化程序.


Jon*_*pan 5

-dealloc被调用时,合同是,它它的方式类层次结构,以确保每一个父类所使用的内存配置正确.[self dealloc]会再次调用你的方法并给你一个无限循环.[super dealloc]撕下你的超类设置的任何东西 - 如果那个超类是NSObject,它也释放了对象占用的内存.

  • 你*永远不会*调用`[self dealloc]`.*自从*.你只在`-dealloc`实现结束时调用``super dealloc]`.但想象一下如果你在那里调用`[self dealloc]`会发生什么.您可以调用自己的代码,这些代码可以调用您自己的代码,代码可以调用您自己的代码,也可以调用您自己的代码等. (2认同)