6

私はライブラリを書いていますが、それは私ではない人々によって使用される可能性があります。

私がクラスを書いたとしましょう:

InterestingClass.h

@interface InterestingClass: NSObject
- (id)initWithIdentifier:(NSString *)Identifier;
@end

InterestingClass.m

@interface InterestingClass()
- (void)interestingMethod;
@end

@implementation InterestingClass
- (id)initWithIdentifier:(NSString *)Identifier {
  self = [super init];
  if (self) {
    [self interestingMethod];
  }
  return self;
}

- (void)interestingMethod {
  //do some interesting stuff
}
@end

誰かが後でライブラリを使用していて、InterestingClass?:のサブクラスを作成することにした場合はどうなりますか?

InterestingSubClass.h

@interface InterestingSubClass: InterestingClass
@end

InterestingSubClass.m

@interface InterestingSubClass()
- (void)interestingMethod;
@end

@implementation InterestingSubClass
- (void)interestingMethod {
  //do some equally interesting, but completely unrelated stuff
}
@end

将来のライブラリユーザーはinitWithIdentifier、スーパークラスのメソッドであるパブリックインターフェイスから見ることができます。このメソッドをオーバーライドする場合、おそらく(正しく)superclassサブクラスの実装でメソッドを呼び出す必要があると想定します。

ただし、スーパークラスの「プライベート」インターフェイスの無関係なメソッドと同じ名前のメソッド(サブクラスのプライベートインターフェイス)を誤って定義した場合はどうなりますか?スーパークラスのプライベートインターフェイスを読まないと、新しいメソッドを作成するだけでなく、スーパークラスの何かをオーバーライドしたこともわかりません。サブクラスの実装が予期せず呼び出される可能性があり、メソッドを呼び出すときにスーパークラスが実行することを期待している作業は実行されません。

私が読んだすべてのSOの質問は、これがObjCの動作方法であり、それを回避する方法がないことを示唆しているようです。これは事実ですか、それとも「プライベート」メソッドがオーバーライドされないように保護するために何かを行うことができますか?

または、スーパークラスからのメソッドの呼び出しをスコープして、サブクラスの実装ではなくスーパークラスの実装が確実に呼び出されるようにする方法はありますか?

4

2 に答える 2

3

AFAIK、あなたが望むことができる最高のものは、オーバーライドがスーパーを呼び出さなければならないことを宣言することです。これを行うには、スーパークラスのメソッドを次のように定義します。

- (void)interestingMethod NS_REQUIRES_SUPER;

これにより、superを呼び出さないオーバーライドにコンパイル時にフラグが立てられます。

于 2014-04-08T18:55:19.077 に答える
1

フレームワークコードの場合、これに対処する簡単な方法は、すべてのプライベートメソッドにプライベートプレフィックスを付けることです。

スタックトレースでは、Appleフレームワークがアンダーバーで始まるプライベートメソッドを呼び出すことがよくあります_

これは、人々があなたのソースを見ることができない外部使用のためのフレームワークを実際に提供している場合にのみ、本当に懸念されます。

注意
:この規則はすでに予約されているため、アンダーバープレフィックスでメソッドを開始しないでください

于 2013-01-31T14:20:17.240 に答える