5

我有一个基本视图控制器,它是许多其他视图控制器的子类。有没有一种方法可以强制执行某些必须在子类中重写的方法?

为了安全起见,比什么都重要。

干杯

4

4 回答 4

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");

就像我说的,这不是真正的编译器保护,但它与您使用不支持抽象方法的语言一样好。

于 2012-11-06T13:31:08.523 回答
7

在其他语言中,这是使用抽象类和方法完成的。在 Objective-C 中没有这样的东西。

您可以获得的最接近的是在超类中引发异常,因此子类被“强制”覆盖它们。

[NSException raise:NSInternalInconsistencyException format:@"Subclasses must override %@", NSStringFromSelector(_cmd)];
于 2012-11-06T13:22:10.733 回答
0

受到 rjstelling 的启发,我以一种更令人满意的方式解决了这个问题:

在您的前缀中,定义:

#define abstract __attribute__((unavailable("abstract method")))

然后您可以添加抽象方法,如下所示:

- (void) getDataIdentifier abstract;

尝试调用此方法将导致编译器语义问题/错误(Xcode 5.1):

'getDataIdentifier' is unavailable: abstract method

更新: 调用该方法似乎不起作用(至少不是从类层次结构中)。如果我设法解决这个问题,我会回来更新。

于 2014-04-26T14:45:01.497 回答
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))的该功能的测试工具中修改的。

这过去也适用于方法,但由于对它的用途的误解而在 2014 年引入了一个错误,现在它只适用于属性,我已通过电子邮件向作者发送电子邮件让他们知道,因此希望它能够恢复原状。要测试错误,您可以向协议添加一个方法,您将看到 ClassB 中没有警告。希望您可以将一些方法更改为只读属性,以至少从中获得一些用途。

以下是一些文档NS_PROTOCOL_REQUIRES_EXPLICIT_IMPLEMENTATIONImplementingAccessibilityforCustomControls nsaccessibilitybutton

于 2018-01-22T10:14:01.973 回答