【问题标题】:Give warning when [super method] is not called未调用 [super method] 时发出警告
【发布时间】:2013-04-18 22:25:15
【问题描述】:

当不使用 ARC 时,在你的 dealloc 方法中没有调用 [super dealloc] 时会收到警告。

我正在尝试用一个经常被子类化的类来实现类似的东西,以在实现子类的人不调用 super 时警告他们。

有什么想法吗?

【问题讨论】:

    标签: objective-c xcode


    【解决方案1】:

    最近的llvm版本增加了一个属性,表示子类必须调用super:

    @interface Barn:NSObject
    - (void)openDoor NS_REQUIRES_SUPER;
    @end
    
    @implementation Barn
    - (void) openDoor
    {
        ;
    }
    @end
    
    @interface HorseBarn:Barn
    @end
    @implementation HorseBarn
    - (void) openDoor
    {
        ;
    }
    @end
    

    编译上面会产生警告:

    Method possibly missing a [super openDoor] call
    

    【讨论】:

    • 按描述工作!谢谢!
    • 非常酷,刚刚在merowing.info/2014/02/ios-tips 上看到了这个但是我想知道为什么苹果不自己用它来做 viewDidAppear 等。
    • @MaxMacLeod 时间;虽然添加声明本身并不难,但它可能会影响相当多的代码库。在如此庞大的代码库中采用语言功能需要时间。
    • @bbum 公平点。我猜他们会在内部实现它并最终在 SDK 更新中推出。
    • NS_REQUIRES_SUPER 是该属性的现代/清洁方法。
    【解决方案2】:

    更新

    查看bbum's answer 以直接告诉编译器子类必须调用super

    原创

    Apple 所做的通常是提供一个钩子,例如viewDidLoad。 Apple 在-[UIViewController viewDidLoad] 基础上没有做任何工作。这是一个空方法。取而代之的是,Apple 在其他地方以您不允许覆盖的私有方法执行其工作,并从该方法调用您的viewDidLoad。因此,即使您忘记在您的 UIViewController 子类中调用 [super viewDidLoad],Apple 的所有工作仍然可以完成。

    也许您可以修改您的 API 以使用类似的模式。

    【讨论】:

    • 您的 cmets 在主要答案之后对 Apple 的不透明实现做出了假设,这些假设可能无效,并且对于其他示例绝对不正确。通常,在覆盖框架方法时,您应该始终调用超级实现,除非另有说明(如 loadView 用于 UIViewController)。
    • 当然,我们不应该依赖未记录的实现细节,我也没有建议我们应该这样做。我指出了一种模式,当super 未被调用时,Apple 使用该模式来减少损害。 (我没有假设 Apple 是否使用该模式。我已经在多个版本的 iOS 上通过测试和反汇编验证了它。当然,他们可能会在未来的某个版本中停止使用它。)
    • 您的原始答案确实提到了编译器警告。我理解你的意图,但你提到的模式不存在。您是在暗示 Apple 的实现是,如果在不调用 super 的情况下覆盖所需的方法,则框架可以处理它。如果你不调用超级实现,有很多例子会出现问题。确实,在viewDidLoad 的特定情况下,您不必为UIViewController 子类调用[super viewDidLoad]。无论如何我都会打电话给超级,因为这是一个好习惯。
    • 我的回答从未提到编译器警告。在我阅读 bbum 的答案之前,我不知道任何相关的编译器警告,该答案是在我回答后 21 分钟发布的。
    • 嘿,不是想和你争论你的答案是什么。我只是指您最初的直接答案,即当不为自定义方法调用 super 时,无法生成编译器警告。与我的主要观点无关。顺便说一句,我只是想澄清一些我认为具有误导性的事情,但总的来说,在帮助人们解决问题方面做得很好。
    【解决方案3】:
    NS_REQUIRES_SUPER
    

    是现代的表达方式

    __attribute__((objc_requires_super))
    

    【讨论】:

      猜你喜欢
      • 2021-07-18
      • 1970-01-01
      • 2012-01-14
      • 1970-01-01
      • 2023-03-28
      • 2019-10-01
      • 2012-06-14
      • 1970-01-01
      • 2022-01-14
      相关资源
      最近更新 更多