を呼び出すことはできますが、のプロパティがタイプであるため、呼び出すことはでき[self.view setNeedsDisplay]
ません。self.view.i
UIViewController
view
UIView
self.myView はすでに viewDidLoad にある self.view に割り当てられています
実際の代入は実行時に発生しますが、コンパイラ エラーはコンパイル時に生成されることに注意してください。コンパイラは、View Controller のメソッドが呼び出される順序を認識していないため、プロパティの元の宣言を超えてプロパティの値の実際の型を推測することはできません。Xcodeに関する限り、self.view
は単なるUIView
.
上でダンが提案したように、プロパティ宣言をオーバーライドして、ビューのタイプがMyView
. とにかく、プロパティを使用するアプローチself.myView
が好まれる場合があります。これにより、インターフェイスを変更せずに将来ビュー階層を変更でき、継承されたメソッドをいじることがありません。とプロパティUITableViewController
は同じビュー インスタンスを返しますが、プロパティの型が異なります。view
tableView
プロパティの型は必ずしもその値の型と同じではないことに注意してください。self.view
のインスタンスに割り当てられている可能性がありますMyView
が、プロパティのタイプは のままですUIView
。割り当てられたオブジェクトの型に関係なく、プロパティのアクセサーは戻り値の型を持つメソッドUIView
です。
したがって、コンパイラに関する限り、そうではないことがわかっていてもself.view
、 は単純な古いにすぎません。UIView
プロパティとは何かについて詳しく説明し、プロパティとインスタンスを区別すると役立つと思います。次のようなプロパティを作成する場合:
@interface MyViewController : UIViewController
@property(strong, nonatomic) MyView *myView;
@end
コンパイラは、それを変数、アクセサ メソッド ("getter")、および mutator メソッド ("setter") に変換します。プロパティは、次のようにメソッドを宣言するための単なる省略形です。
@interface MyViewController : UIViewController
{
MyView *_myView;
}
- (MyView *)myView; // accessor / getter
- (void)setMyView:(MyView *)myView; // mutator / setter
@end
@implementation MyViewController
- (MyView *)myView
{
return _myView;
}
- (void)setMyView:(MyView *)myView
{
_myView = myView;
}
@end
self.myView
、またはを呼び出すときself.view
は、実際にはアクセサ メソッドを呼び出しています。[self myView]
またはと同等[self view]
です。返されるのは、メモリ内のオブジェクトへのポインターです。を割り当てたのでself.view = self.myView
、両方のプロパティが同じオブジェクトに設定されます。したがって、両方とも同じオブジェクトへのポインタを返しますself.view
。self.myView
要約する:
- は のサブクラスであるため、代入
self.view = self.myView
はコンパイル エラーを生成しません。のサブクラスではないため、代入すると警告が生成されることに注意してください。MyView
UIView
self.myView = self.view
UIView
MyView
- 同じインスタンスが両方のプロパティに割り当てられているため、呼び出す
[self.view setNeedsDisplay]
とmyView
、それ自体が描画されます。両方のプロパティの説明 ( ) をログに記録すると、それらのメモリ アドレスが同じであることがわかります。NSLog(@"view=%@, myView=%@", self.view, self.myView)
- プロパティがタイプを持つように宣言されており、という名前のメソッドがない
self.view.i
ため、呼び出すことができません。view
UIView
UIView
i