UIViewレイヤーのようなよく知られたセレクターを持つクラスがあります。誰かがUIViewをサブクラス化し、別の目的で自分の「レイヤー」セレクターを宣言した場合はどうなりますか?そして、UIKit自体のような他のいくつかのフレームワークがUIViewインスタンスのレイヤーを呼び出します。これはサブクラスの「レイヤー」を呼び出し、クラッシュを引き起こしますか?
4 に答える
既存のメソッドをオーバーライドして、まったく異なる目的で使用しないでください。
UIView
サブクラスがある場合、オーバーライドlayer
してまったく異なるものを返すと、フレームワーククラス(オーバーライドの目的を認識していない)がlayer
メソッドを呼び出し、予期しないものを返します。物事はかなり早く南下します。
いいえ、すべてのインスタンスはそれがどのクラスであるかを知っていますUIView
。サブクラスで何かをオーバーライドした後でも作成した場合でも、UIView
はそのバージョンのメソッドを使用します。これは継承の非常に基本的なことです。子クラスは親に影響を与えるべきではありません。
@interface Stuper : NSObject
- (void)layer;
@end
@implementation Stuper
- (void)layer {
NSLog(@"superclass");
}
@end
@interface Stub : Stuper
@end
@implementation Stub
- (void)layer { // Override layer
NSLog(@"subclass");
}
@end
Stuper * p = [Stuper new];
Stub * b = [Stub new];
[p layer]; // Prints "superclass"
[b layer]; // Prints "subclass"
ただし、これは、カテゴリ内のメソッドをオーバーライドする場合に発生する可能性があるため、そうすべきではありません。元のクラスのすべてのインスタンスは新しいバージョンのメソッドを使用するため、特にフレームワーククラスで大きな問題が発生する可能性があります。
@interface Stuper (BadIdea)
- (void)layer; // Clobber layer
@end
@implementation Stuper (BadIdea)
- (void)layer {
NSAssert(NO, @"Sucker!");
}
@end
Stuper * p = [Stuper new];
[p layer]; // Almost certainly doesn't do what the caller was expecting
フレームワークオブジェクトをサブクラス化する場合、最初に確認する必要があるのは、Appleが提供するクラスリファレンスです。
UIView
クラスリファレンスについては、ここをクリックしてください。。
クラスリファレンスには、サブクラス化に関する重要な情報を含む「サブクラス化に関する注意事項」というタイトルのセクションがあります。このセクションには、オーバーライドする必要のあるメソッド、オーバーライドする必要のあるメソッド、およびオーバーライドしてはならないメソッドに関する情報が含まれています。
この場合、layer
メソッドは言及されていませんが、オーバーライドするメソッドの下に次のようになっています。
- layerClass-このメソッドは、ビューでバッキングストアに別のCoreAnimationレイヤーを使用する場合にのみ実装してください。たとえば、OpenGL ESを使用して描画を行う場合は、このメソッドをオーバーライドしてCAEAGLLayerクラスを返す必要があります。
もう少し詳しく見てみると、layerClass
プロパティの説明の下に、次のように表示されます。
layerClass
このクラスのインスタンスのレイヤーを作成するために使用されるクラスを返します。
+ (Class)layerClass
戻り値
ビューのCoreAnimationレイヤーを作成するために使用されるクラス。
説明このメソッドは、デフォルトでCALayerクラスオブジェクトを返します。サブクラスはこのメソッドをオーバーライドし、必要に応じて別のレイヤークラスを返すことができます。たとえば、OpenGL ESを使用して描画を行う場合は、このメソッドをオーバーライドして、CAEAGLLayerクラスのクラスオブジェクトを返します。このメソッドは、対応するレイヤーオブジェクトを作成するために、ビューの作成の早い段階で1回だけ呼び出されます。
したがって、これは、返されることが期待されるクラスを変更できることを示していますが、それは「異なるレイヤークラス」(つまり、のサブクラス)である必要があります。他の多くの関数は、レイヤーのレイアウトやサイズ変更などの際にレイヤーと相互作用します。それらのガイドラインに従わないと、大きな問題が発生します。layer
CALayer
注:
これはすべて、サブクラス化されたオブジェクトに適用されます。サブクラスに変更を加えたときに、親クラス(この場合)に触れたり適用したりするUIView
ことはありません。したがって、UIViewオブジェクトを壊すことを心配する必要はありません。独自のサブクラス化されたオブジェクトだけが、クラッシュや未定義の動作を引き起こす可能性があります。
それはオブジェクト指向言語の基礎のように聞こえます。意図に似たクラスを選択し、そのサブクラスを作成して操作し、目的の操作を実行します。ほとんどの場合、コンパイラにクラスのその機能をオーバーライドして、基本クラスを呼び出さないようにする必要があります。