Objective-C停止一个方法的继承流程

时间:2016-05-19 06:50:14

标签: objective-c inheritance

假设ParentClass有一个公共初始值设定项initWithSomething

-(id) initWithSomething: (NSString *)something;

现在在ChildClass,我使用了这个初始化程序,但我不希望任何扩展ChildClass的人都可以访问它。相反,我只希望他们能够访问我更具体的初始化程序initWithSomethingSpecific

因此GrandChildClass只能访问initWithSomethingSpecific,而不是initWithSomething

这在Objective-C中是否可行?

4 个答案:

答案 0 :(得分:3)

要执行此操作,请使用

方法覆盖ParentClass中的ChildClass方法
  1. 无法轻松调用,
  2. 如果被召唤(被某人确定)否认它存在......
  3. 要实现(1)您使用unavailable属性,在ChildClass.h中写下如下内容:

    // prevent use of inherited initWithSomething outside of this implementation
    - (instancetype) initWithSomething:(Something *)something __attribute__((unavailable("Use -initWithSomethingSpecific: instead")));
    

    这将阻止Xcode在代码完成期间提供它,如果程序员仍然编写它将产生编译时错误,使消息使用initWithSomethingSpecific

    要解决(2),您提供了调用NSObject' doesNotRecognizeSelector:的方法的实现。例如,在ChildClass.m中写下类似的内容:

    // prevent use of inherited initWithSomething outside of this implementation
    - (instancetype) initWithSomething:(Something *)something
    {
       [self doesNotRecognizeSelector:_cmd]; // for any code which makes it here make it look like the method does not exist
       return nil;                           // will never reach here
    }
    

    _cmd是每个Objective-C方法的标准隐藏参数,其值是方法本身的选择器。)

    如果调用此方法,将生成未实现方法的常见错误和堆栈跟踪。

    HTH

答案 1 :(得分:0)

不可能强制执行,不。您应该记录更具体的初始化程序的使用,并将其保留。如果您没有提供文档,请确保在头文件中对声明进行大量评论。

如果您能够在[ChildClass initWithSomething:]中使用相同的方法签名,那么[ParentClass initWithSomething:]的子类无法进入ChildClass

答案 2 :(得分:0)

您可以[ChildClass initWithSomething:]返回nil 然后实施initWithSomethingSpecific

答案 3 :(得分:0)

我认为您正在寻找UNAVAILABLE_ATTRIBUTE宏。 将此代码放在ChildClass标题中:

- (instancetype)initWithSomething:(NSString *)something UNAVAILABLE_ATTRIBUTE;

另外,  如果您需要完全保护,可以在initWithSomething中实施ChildClass并提出异常。