我有一个基本视图控制器,许多其他视图控制器是子类。有没有办法强制执行某些必须在子类中重写的方法?
为了安全起见,最重要的是。
干杯
答案 0 :(得分:12)
在Xcode中(使用clang等)我喜欢使用__attribute__((unavailable(...)))
标记抽象类,以便在尝试使用它时收到错误/警告。
它可以防止意外使用该方法。
在基类@interface
标记“抽象”方法:
- (void)myAbstractMethod:(id)param1 __attribute__((unavailable("You should always override this")));
更进一步,我创建了一个宏:
#define UnavailableMacro(msg) __attribute__((unavailable(msg)))
这可以让你这样做:
- (void)myAbstractMethod:(id)param1 UnavailableMacro("You should always override this");
就像我说的,这不是真正的编译器保护,但它与你不会使用不支持抽象方法的语言一样好。
答案 1 :(得分:7)
在其他语言中,这是使用抽象类和方法完成的。在Objective-C中没有这样的东西。
最接近的是在超类中引发异常,因此子类被“强制”覆盖它们。
[NSException raise:NSInternalInconsistencyException format:@"Subclasses must override %@", NSStringFromSelector(_cmd)];
答案 2 :(得分:0)
受到rjstelling的启发,我以更令人满意的方式解决了这个问题:
在您的前缀中,定义:
#define abstract __attribute__((unavailable("abstract method")))
然后你可以按如下方式添加抽象方法:
- (void) getDataIdentifier abstract;
尝试调用此方法将导致编译器语义问题/错误(Xcode 5.1):
'getDataIdentifier' is unavailable: abstract method
<强>更新强> 调用该方法似乎不起作用(至少不是在类层次结构中)。如果我设法解决这个问题,我会回来更新。
答案 3 :(得分:0)
您可以通过使用LLVM功能,在编译时要求子类实现属性(为什么不是方法见下文),如下所示:
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重新实现协议时,它会显示缺少属性方法的expected-warning
。 NS_PROTOCOL_REQUIRES_EXPLICIT_IMPLEMENTATION
只是__attribute__((objc_protocol_requires_explicit_implementation))
的一个宏,此代码示例是从该功能here的测试工具中修改的。
这也常用于方法,但是2014年通过misunderstanding in what it is for引入了一个错误,现在它只适用于属性,我已经通过电子邮件通知作者让他们知道,所以希望它改回到它的方式是。要测试该错误,您可以在协议中添加一个方法,您将看到ClassB中没有警告。希望你可以改变你的一些方法来只读属性,至少可以使用它。
以下是NS_PROTOCOL_REQUIRES_EXPLICIT_IMPLEMENTATION
的一些文档:
ImplementingAccessibilityforCustomControls
nsaccessibilitybutton
如果您使用过这个,那么如果您还没有成为ObjC专家,那就拍拍自己吧!