0

私は非常に愚かだと感じていますが... CocoaTouch UIクラスから派生したカスタムタイプでインスタンス変数を初期化する正しい方法は何ですか?

から派生したタイプがUIViewControllerあるとしましょうTRUIController。私はivarを次のように定義しました:

@implementation TRUIController
{
    NSNumberFormatter *_numberFormatter;
}
@end

_numberFormatterまた、初期化コードを、などのUIメソッドの前に実行する場合は、どこに配置する必要がありviewDidLoadますか?

他の言語では、ivarを作成しconstructor、呼び出してから初期化します。しかし、それは単にでは機能しbase constructorません。objective-cCocoa Touch

上記の場合、

-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibBundleOrNil bundle:nibBundleOrNil];
    if(self)
    {
        //init ivars
    }
    return self;
}

それは機能しません、私は他のinitWithBlaBla方法を試してみて、最後にinit実際に呼ばれている、その場合は-を見つけます-initWithCoder:

ここで、UITableViewCellから派生したクラスがあるとしましょう。繰り返しますが、NSNumberFormatterivarを初期化する必要があります。ivarをオーバーライドinit:、呼び出し、初期化できないのはなぜですか?super

すべてのタイプに単一の共通の初期化メソッドを持たないというこの奇妙な設計決定の背後にある考え方は何ですか?

派生型でivarを初期化する唯一の方法ですか?今回オーバーライドする方法を見つけるために、毎回調査を行いますか?

私は何かを逃したことがありますか?それは非常に愚か/直感的でない/エラーが発生しやすいと感じるからです

4

2 に答える 2

2

指定された初期化子をオーバーライドする必要があります。

公式ドキュメントから

指定初期化子は、スーパークラスのinitメソッドを呼び出すクラスのinitメソッドです。(他の初期化子は、クラスによって定義されたinitメソッドを呼び出します。)すべてのパブリッククラスには、1つ以上の指定された初期化子が必要です。指定された初期化子の例として、NSViewのinitWithFrame:およびNSResponderのinitメソッドがあります。NSStringやクラスクラスターの前にある他の抽象クラスの場合のように、initメソッドがオーバーライドされることを意図していない場合、サブクラスはそれ自体を実装することが期待されます。

この情報はクラスをサブクラス化したい人にとって重要であるため、指定された初期化子は明確に識別される必要があります。サブクラスは指定された初期化子をオーバーライドするだけで、他のすべての初期化子は設計どおりに機能します。

フレームワークのクラスを実装する場合、多くの場合、そのアーカイブメソッド(initWithCoder:およびencodeWithCoder:)も実装する必要があります。オブジェクトがアーカイブ解除されたときに発生しない初期化コードパスでの処理を行わないように注意してください。これを実現する良い方法は、クラスがアーカイブを実装している場合、指定された初期化子とinitWithCoder:(指定された初期化子自体)から共通ルーチンを呼び出すことです。

どの初期化子が指定されたものであるかを確認するためのドキュメントを読み、それをオーバーライドします。

UIViewController のドキュメントによると、initWithNibName:bundle:このクラスの指定された初期化子はそのクラスをオーバーライドする必要がありますが、プログラムでクラスをインスタンス化してない場合(たとえば、nib / storyboardからロードしている場合)、アーカイブメソッドをオーバーライドする必要がありますinitWithCoder:

ドキュメントで示唆されているように、初期化のルーチンを作成し、指定された初期化子とアーカイブメソッドの両方から呼び出すことができます。

于 2013-01-23T19:27:21.577 に答える
1

通常、指定された初期化子を開始点として使用することは理にかなっていますが、確信が持てない場合は、これが常に使用されるものであり、それほど意味がありません。

したがって、個人的には、ある段階で使用される可能性が高いとわかっているinitメソッドから呼び出されるセットアップメソッドを作成することを好みます。ViewControllerの場合、通常は代わりにviewDidLoadからsetupメソッドを呼び出します(もちろん、この段階の前に必要な状態がない限り)。

于 2013-01-23T19:29:32.693 に答える