18

サブクラスで、スーパー クラスで公開されていないメソッドをオーバーライドしています。スーパークラスの実装を正常にオーバーライドしているため、正しい署名を持っていることがわかります。ただし、新しい実装の一部として、サブクラスの実装からスーパークラスの実装を呼び出す必要があります。

公開されていないため、次の呼び出しを介してメソッドを呼び出す必要がありますperformSelector

SEL superClassSelector = NSSelectorFromString(@"methodToInvoke");
[super performSelector:superClassSelector];

ただし、私のアプリケーションでは、スーパークラスの実装を呼び出そうとするたびに、サブクラスの実装が呼び出される無限再帰ループが発生します。

何かご意見は?

これは異例の状況であることは承知していますが、残念ながら、私がやろうとしていることを回避する方法はありません。

4

3 に答える 3

9

performSelector:スーパークラスに渡すセレクターではなく、のみを送信しているため、これは機能しません。performSelector:現在のクラスのメソッド リストでメソッドを検索します。したがって、同じサブクラスの実装になります。

これを行う最も簡単な方法は、次のように独自の呼び出しを記述することobjc_msgSendSuper()です。

// Top level (this struct isn't exposed in the runtime header for some reason)
struct objc_super
{
    id __unsafe_unretained reciever;
    Class __unsafe_unretained superklass;
};

// In the subclass's method
struct objc_super sup = {self, [self superclass]};
objc_msgSendSuper(&sup, _cmd, other, args, go, here);

Rob Napier が以下で指摘しているように、これは一般的なケースで問題を引き起こす可能性があります。メソッドには戻り値がないという前提に基づいて、これを提案しました。

于 2013-05-21T20:18:06.613 に答える
2

1つの方法は、公開しようとしているメソッドを使用して、別のファイルにクラスのカテゴリを作成することです

@interface MyClass (ProtectedMethods)

- (void)myMethod;

@end

そして.m

@implementation MyClass (ProtectedMethods)

- (void)myMethod {

}

@end

次に、このカテゴリを .m ファイルからインポートすれば準備完了です。それは最も美しいものではありませんが、うまくいくでしょう

于 2013-05-21T20:04:30.673 に答える