iOS Subclassing and compulsory methods
我有一个基础视图控制器,它是许多其他视图控制器的子类。是否有一种强制某些方法的方法必须在子类中重写?
为了安全起见。
干杯
在Xcode(使用clang等)中,我喜欢使用
它提供了一些防止意外使用该方法的保护。
例子在基类
1 | - (void)myAbstractMethod:(id)param1 __attribute__((unavailable("You should always override this"))); |
更进一步,我创建了一个宏:
1 | #define UnavailableMacro(msg) __attribute__((unavailable(msg))) |
这样可以做到:
1 | - (void)myAbstractMethod:(id)param1 UnavailableMacro("You should always override this"); |
正如我所说,这不是真正的编译器保护,但它和您使用不支持抽象方法的语言一样好。
在其他语言中,这是使用抽象类和方法完成的。在目标C中没有这样的东西。
最接近的方法是在超类中引发一个异常,这样子类就被"强制"覆盖了。
1 | [NSException raise:NSInternalInconsistencyException format:@"Subclasses must override %@", NSStringFromSelector(_cmd)]; |
您可以要求子类在编译时使用以下LLVM特性来实现属性(为什么不使用下面的方法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | NS_PROTOCOL_REQUIRES_EXPLICIT_IMPLEMENTATION @protocol Protocol @property (readonly) id theWorstOfTimes; // expected-note {{property declared here}} @end // In this example, ClassA adopts the protocol. @interface ClassA : NSObject <Protocol> @property (readonly) id theWorstOfTimes; @end @implementation ClassA - (id)theWorstOfTimes{ return nil; // default implementation does nothing } @end // This class subclasses ClassA (which also adopts 'Protocol'). @interface ClassB : ClassA <Protocol> @end @implementation ClassB // expected-warning {{property 'theWorstOfTimes' requires method 'theWorstOfTimes' to be defined - use @synthesize, @dynamic or provide a method implementation in this class implementation}} @end |
如您所见,当ClassB重新实现协议时,它显示
这种方法过去也适用于方法,但2014年由于对其用途的误解而引入了一个bug,现在它只适用于属性,我给作者发了电子邮件,希望他们能意识到它是如何改变的。要测试这个bug,您可以向协议中添加一个方法,您将看到ClassB中没有警告。希望您可以将一些方法更改为只读属性,以至少从中获得一些使用。
以下是有关
如果你用了这个,那么如果你还没有成为一个objc专家的话,请拍拍自己的背!
在RJStalking的启发下,我以一种更令人满意的方式解决了这个问题:
在前缀中,定义:
1 | #define abstract __attribute__((unavailable("abstract method"))) |
然后可以添加如下抽象方法:
1 | - (void) getDataIdentifier abstract; |
尝试调用此方法将导致编译器语义问题/错误(xcode 5.1):
1 | 'getDataIdentifier' is unavailable: abstract method |
更新:调用方法似乎不起作用(至少不是从类层次结构中调用)。如果我能解决这个问题,我会回来提供一个更新。