客观c类和继承

Wil*_*sch 12 iphone inheritance objective-c categories ios

如果在该类的类和类别中定义了一个方法,则未定义将调用哪个实现.

但这如何与继承相互作用?特别:

  • 给定一个超类类别方法和子类中的常规方法,是否可以保证子类实现在子类成员上调用时会获胜?
  • 给定一个超类常规方法和一个试图覆盖它的子类类别方法,是否保证子类类实现在子类成员上调用时会获胜?
  • 给定一个超类类别方法和一个子类类别方法,是否保证子类类别方法在子类成员上调用时会获胜?

Jos*_*erg 49

让我们这样说吧.不要使用类别,句号,永远,答案结束覆盖方法.

  • 太糟糕了,我今天没有投票支持这一点. (2认同)

bbu*_*bum 40

如果在该类的类和类别中定义了一个方法,则未定义将调用哪个实现.

那是不对的; 类别方法总是会赢.但是,如果你有多个类别实现相同的方法,那么什么是行不通的,那么"哪一个获胜"是未定义的.

它通常是"最后装载的胜利",但这也不是一个严格的规则.

请注意,由于许多类在内部将其实现划分为不同的类别以用于代码组织目的,因此无论如何都不能依赖第一个规则.

简而言之,约书亚所说的; 不要使用类别覆盖方法.

除了继承的原因,当你这样做时,你也会恶意破坏封装.基于类的实现不是覆盖现有方法,而是完全取代它.因此,如果您不重现每个最后的内部实现细节,包括错误,您的替换将无法正常工作并且调试它将很难.

  • @LeoNatan不,真的,系统类中的混合方法很脆弱,会导致崩溃和/或未定义的行为.虽然在混合实现中调用原始实现确实可以降低风险,但它仍然会以破坏封装并导致脆弱性的方式更改系统提供的实现.在我编写,维护和调试大规模Objective-C应用程序的20多年中,我非常有信心声称方法调配是一个不应该在生产代码中使用的有趣的黑客. (5认同)
  • @LeoNatan来自文档:"原生应用程序是使用iOS系统框架和Objective-C语言构建的." 所以,是的,Foundation/Cocoa/UIKit/CoreData(以及Apple提供的所有其他框架)都是"System Frameworks",你的代码不应该修改他们的行为,超出了通过该Framework的公共API可用的行为.Swizzling与直接使用iVars无关; 它破坏了封装,很脆弱,并导致应用程序崩溃.为了注入一点幽默,UIKit团队留下了一张便条:http://openradar.appspot.com/7044974 (5认同)
  • @LeoNatan不,*没有*,**没有**....***Swizzling不是答案.***如果您的应用程序调高系统方法,那就是针对应用商店政策.并且有充分理由因为它通常会导致脆弱,崩溃的代码,这些代码可能在任何给定平台或更新上展现出新的,完全未定义的行为. (4认同)
  • @LeoNatan您可以自由地使用调配或任何您想要实现自己功能的机制.使用相同的机制修改系统提供的类是要求麻烦(和拒绝,正如该问题所证明的那样).仅仅因为工具可以服务于特定功能并不意味着使用工具来实现该功能; 我可以用锤子开螺丝,但我生产的橱柜会很糟糕. (3认同)
  • 是的 - 子类实现总是会赢. (2认同)