3

Class1とClass2の2つのクラスがあり、2番目のクラスは最初のクラスから継承されています。目標を達成するには、Class1の-updateメソッドをオーバーライドする必要があります。継承メソッドの-updateメソッドの変更はコードの途中で行われるため、[superupdate]は使用できません。そのため、元のメソッドを親から継承されたクラスにコピーアンドペーストする必要があります。このメソッドは親のプライベートメソッドを使用しているため、オーバーライドしようとすると、Class2はClass1.hのみをインポートするため、プライベートメソッドがないという警告が表示されます。明確にするために、ここにコードがあります:

Class1.h:

@interface Class1 : NSObject
-(void) update;
@end

Class1.m:

@interface Class1 (Private)
-(void) private1;
-(void) private2;
@end

@implementation Class1

-(void) update
{
    [self private1];
    [self private2];
}

-(void) private1
{
    // some code
}

-(void) private2
{
    // another code
}

@end

Class2.h:

@interface Class2 : Class1
-(void) update;
@end

Class2.m:

@implementation Class2

-(void) update
{
    [self private1]; // warning here
    // do my own stuff between private methods, that is the reason of inheritance
    [self private2]; // warning too
}

@end

また、Class1は私の所有権ではなく、オープンソースライブラリ(正確にはCocos3D)からのものであるため、変更できませんでした(そのため、継承を行います)。

問題は、警告を削除するにはどうすればよいですか?私が見ることができる唯一の解決策は、プライベートメソッドのシグネチャをClass2にコピーすることですが、それは汚いトリックのようです。または、誰かが警告を削除する方法ではなく、方法をよりうまく変更するという私の目標を達成する方法を指摘するなら、それは完璧でしょう。

4

4 に答える 4

7

スウィズリング、performSelector:、またはその他のランタイム バグは必要ありません。

これを移動またはコピーするだけです:

@interface Class1 (Private)
-(void) private1;
-(void) private2;
@end

サブクラスの .m ファイルの先頭に。

通常、@protectedメソッドのスコープのようなものを達成しようとするとき、そのような宣言はヘッダーファイルのようになり、そのヘッダーはXcodeClass1_Private.hのロールに設定されます。private

他の人が指摘したように、このメカニズムを介してプライベート メソッドを公開することは少し危険です。Cocos2D がオープン ソースであることを考えると、その危険性は多少軽減されるか、いつでも直接変更することができます。もちろん、そうすることは、維持するのにコストがかかるブランチを効果的に持つことを意味します。

これが他の開発者が行う可能性が高いものである場合は、Cocos2D にバグを報告して、サブクラス化の目的でメソッドを公開するように要求することをお勧めします。

于 2013-03-07T16:18:12.043 に答える
2

Apple がこれを行う方法は、サブクラスでオーバーライドできるすべてのメソッドを public にすることですが、直接呼び出すべきではなく、オーバーライドするためだけに存在するという事実を文書化しています。Apple のコードのドキュメントは (通常) 包括的であり、頻繁に参照されるため、これは機能します。もちろん、典型的なサードパーティのコードは十分に文書化されておらず、文書が読まれる可能性も高くありません...

別の解決策: 私はしばしば「MyClass+SubclassMethods.h」という 2 番目のヘッダーを作成し、サブクラスのオーバーライド可能を公に宣言しますが、それ以外の場合はそこのカテゴリでプライベート メソッドを宣言します。基本クラスとサブクラスのユーザーのソース ファイルでは、これはインポートされないため、メソッドは (事実上) プライベートのままです。基本クラスのサブクラスでは、「MyClass+SubclassMethods.h」をインポートして、これらのメソッドをオーバーライド/呼び出しできるようにします。これは完璧な解決策ではありませんが、Objective-C の「保護された」メソッドの概念がなければ、もっと優れた方法があるとは思えません。

于 2013-03-07T16:08:56.200 に答える
-2

カテゴリを使用してこの問題を解決し、元のクラスを拡張し、メソッドの入れ替えを試みて、目的の動作を実現できるはずです。

于 2013-03-07T13:56:56.420 に答える