24

ソースがない Objective C クラスのメソッドをオーバーライドしたいと考えています。

調べたところ、カテゴリでこれを実行できるように思われますが、古いメソッドの結果を取得するために super を使用して、新しいメソッドで古いメソッドの結果を使用したいと考えています。

ただし、これを試すたびに、メソッドが呼び出されますが、「スーパー」は nil です...理由はありますか? XCode 2.2 SDK を使用して iPhone 開発を行っています。私は間違いなくクラスのインスタンスで作業しており、クラスのメソッドはインスタンス メソッドです。

@implementation SampleClass (filePathResolver)
-(NSString*) fullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [super fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}

注と説明: Apple Docs で確認できることから、これは許可されるべきだと思われますか?

カテゴリーのドキュメント (developer.apple.com): カテゴリーが継承されたメソッドをオーバーライドする場合、通常どおり、カテゴリー内のメソッドはスーパーへのメッセージを介して継承された実装を呼び出すことができます。ただし、カテゴリのクラスに既に存在するメソッドをカテゴリがオーバーライドする場合、元の実装を呼び出す方法はありません。

4

3 に答える 3

29

カテゴリは元のクラスを拡張しますが、サブクラス化しないため、 を呼び出してsuperもメソッドが見つかりません。

あなたが望むのはMethod Swizzlingと呼ばれるものです。ただし、コードによって何かが壊れる可能性があることに注意してください。古い Objective-C ランタイムでの Method Swizzling についてScot Stevenson によって書かれた Theocacaoに関する記事があります。Matt Gallagher による Cocoa with Loveには、新しい Objective-C 2.0 ランタイムでの Method Swizzling とその単純な代替に関する記事があります。

または、クラスをサブクラス化し、サブクラスを使用するか+ (void)poseAsClass:(Class)aClass、スーパークラスを置き換えるために使用することもできます。アップルは次のように書いています。

ポージング クラスによって定義されたメソッドは、 へのメッセージを通じて、superそれがオーバーライドするスーパークラス メソッドを組み込むことができます。

poseAsClass:Apple はMac OS X 10.5 で非推奨になったことに注意してください。

于 2009-09-10T12:47:07.847 に答える
8

このクラスに対してコーディングする場合は、セレクターの名前をコードで使用できる名前に変更し、元のセレクターを on で呼び出しますself

@implementation SampleClass (filePathResolver)
-(NSString*) myFullPathFromRelativePath:(NSString*) relPath
{
    NSString *result = [self fullPathFromRelativePath: relPath];

  ... do some stuff with the old result

    return result;
}

そのクラスのこのセレクターのデフォルトの実装をオーバーライドする場合は、メソッド スウィズリングアプローチを使用する必要があります。

于 2009-09-10T13:16:00.070 に答える