每个视图类都有多个 init 方法——已经包含在 UIView 中的方法,然后是其他方法——它们中的每一个都以相同的方式设置相同的元素。因此,我通常让他们都运行一个[self initialSetup];
方法,其中包括设置所有这些元素。
我遇到的问题是,如果一个子类也有一个 initialSetup 方法,它将覆盖超类的 initialSetup 方法,因此超类必须让该方法是公共的才能仍然起作用。这会导致组织问题,因为除了从 init 之外,永远不应该调用该方法,因此没有理由公开。
每个视图类都有多个 init 方法——已经包含在 UIView 中的方法,然后是其他方法——它们中的每一个都以相同的方式设置相同的元素。因此,我通常让他们都运行一个[self initialSetup];
方法,其中包括设置所有这些元素。
我遇到的问题是,如果一个子类也有一个 initialSetup 方法,它将覆盖超类的 initialSetup 方法,因此超类必须让该方法是公共的才能仍然起作用。这会导致组织问题,因为除了从 init 之外,永远不应该调用该方法,因此没有理由公开。
将名称更改为initialSetup
类似initialSetupClassName
- 子类,即使它们不小心使用了相同的模式,也不会使用相同的名称,因为它们具有不同的类名。
你也可以为你不想被调用的私有方法使用“_”前缀,但是子类也可以这样做。
您遇到了一个没有完美解决方案的问题。理想情况下,您拥有的是一种在正常意义上不能被子类化的方法,它只能被该确切类型的类的实例访问。
如果这是一个风险,通常的做法似乎是将类名合并到 setup 方法中。所以不是initialSetup
你有类似的东西myViewSubclassInitialSetup
。
您还可以在方法的顶部添加类似这样的内容:
NSAssert([self isMemberOfClass:[ThisClass class]],
@"IniitalSetup called by sub- or superclass")
然后,如果子类或超类最终调用您的 init 方法,您的调试构建将引发异常。这将为您提供一个断点和堆栈跟踪的位置,让您可以非常快速地找到问题。
它不会向您的发布版本添加任何代码。
It sounds like you are missing a designated initializer. Designate one initializer as the official one that actually performs the setup, and have all the others just call that with some degree of customization. Usually the designated initializer will be the one with the most detail — for example, if you have init
, initWithName:
, initWithName:age:
and initAsFiveYearOldNamed:
, the designated initializer will be initWithName:age:
and the other initializers would just call that method with the arguments filled in appropriately.
不幸的是Objective C
,它没有提供一种以“干净”的方式实现这一目标的方法。理想的解决方案是受保护的方法。但这是不可能的Objective C
Apple had this problem, when they were creating the UIGestureRecognizer
. There were some methods they really didn't want to get called by somebody, but which had to be overwritten by subclasses. The way they chose to deal with this, was to create a seperate header file (UIGestureRecognizerSubclass.h
), that contains a category to the original UIGestureRecognizer
with those "protected" methods. The additional header is only to be imported by subclasses (i.e. for subclassing purposes). See UIGestureRecognizer Class Reference for some details.
Of course that doesn't prevent anybody from misusing the additional header file, but at least it clearly states your intention and keeps your code well structured. Also you won't be "bothered" by autocompletion for the additional methods, when just using the class.
Personally I only use an additional header, if it is extremely important that nobody calls it directly. In most cases I think it's ok to use public methods and make a note for what it's inteded. The iOS Framework also has many of these cases. F.e. many methods of UIViewController
's viewDidLoad
etc.