在不重复代码的情况下执行init的最佳方法

时间:2013-04-12 22:37:35

标签: iphone ios objective-c xcode class

每个视图类都有多个init方法 - 已经作为UIView的一部分包含的方法,然后是其他方法 - 并且每个方法都以相同的方式设置相同的元素。因此,我通常让它们都运行[self initialSetup];方法,其中包括设置所有这些元素。

我遇到的问题是,如果一个子类也有一个initialSetup方法,它将覆盖超类的initialSetup方法,因此超类必须将该方法公开才能仍然起作用。这会导致组织问题,因为永远不应该从init调用该方法,因此没有理由公开。

4 个答案:

答案 0 :(得分:2)

initialSetup的名称更改为initialSetupClassName - 子类,即使他们意外使用了相同的模式,也不会使用与具有不同类名的名称相同的名称。

你也可以为你不想被调用的私有方法使用“_”前缀,但是子类也可以这样做。

答案 1 :(得分:2)

你遇到了一个问题,那就是没有完美的解决办法。你理想情况下的方法是一种方法,它不能在正常意义上进行子类化,只能用于那种确切类型的类的实例。

如果这是一种风险,通常的做法似乎是将类名合并到setup方法中。因此,initialSetup代替myViewSubclassInitialSetup,而不是NSAssert([self isMemberOfClass:[ThisClass class]], @"IniitalSetup called by sub- or superclass")

您还可以在方法的顶部添加类似的内容:

{{1}}

如果子类或超类最终调用init方法,那么调试版本将引发异常。这将为您提供断点和堆栈跟踪的位置,以便您可以非常快速地找到问题。

它不会向您的发布版本添加任何代码。

答案 2 :(得分:2)

听起来你错过了一个指定的初始化程序。将一个初始化程序指定为实际执行设置的正式初始化程序,并让所有其他初始化程序仅通过某种程度的自定义调用它。通常,指定的初始值设定项将是最详细的初始值设定项 - 例如,如果您有initinitWithName:initWithName:age:initAsFiveYearOldNamed:,则指定的初始值设定项将为{{ 1}}和其他初始化程序只会在适当填充参数的情况下调用该方法。

答案 3 :(得分:1)

不幸的是Objective C没有提供一种以“干净”的方式实现这一目标的方法。理想的解决方案是受保护的方法。但这在Objective C

中是不可能的

Apple在创建UIGestureRecognizer时遇到了这个问题。有些方法他们真的不想被某人调用,但必须被子类覆盖。他们选择处理此问题的方法是创建一个单独的头文件(UIGestureRecognizerSubclass.h),其中包含原始UIGestureRecognizer的类别和那些“受保护”方法。附加标题仅由子类导入(即用于子类化目的)。有关详细信息,请参阅UIGestureRecognizer Class Reference

当然,这并不妨碍任何人滥用额外的头文件,但至少它清楚地表明了你的意图并保持你的代码结构良好。此外,当您使用该类时,您不会因其他方法的自动完成而“烦恼”。

我个人只使用额外的标题,如果没有人直接调用它是非常重要的。在大多数情况下,我认为使用公共方法并记下它的含义是可以的。 iOS框架也有许多这样的情况。 F.E. UIViewController的{​​{1}}等许多方法