3

Objective Cでは、カスタムinitメソッドはスーパークラスの指定された初期化子を呼び出す必要があります。NSViewのサブクラスの次のカスタムinitメソッドについて考えてみます。

- (void)initWithFrame:(CGRect)aFrame andName:(NSString *)aName {
    if(self = [super initWithFrame:aFrame]){
        //set up object
    }
}

ただし、MacRubyはsuperキーワードのみを提供し、スーパークラスで同じメソッドを呼び出そうとします。ただし、これはカスタム初期化子であるため、スーパークラスにはそのようなメソッドはありません。

これを解決する標準的な方法は何ですか?私はこの質問を見ました:MacRubyカスタム初期化子ですが、答えをよく理解しているとは言えません。また、広く受け入れられている解決策ではないようです。MacRubyは、その投稿が書かれたときよりも数年古いので、より明確で標準的なソリューションが存在することを望んでいます。

4

2 に答える 2

4

rubymotion(そしてMacRubyはこの振る舞いを共有していると思います)には、2つのタイプのクラスがあります。を使用する純粋なRubyとinitialize、objective-cクラスから派生したクラスです。2つを混ぜないのが最善です。Objective-cクラスをサブクラス化する場合は、initメソッドを使用する必要があります。initializeメソッドが呼び出されることはありません!

これは、NSObject##newメソッドがinitではなくを呼び出すためですinitialize(実際には、これでも過度に単純化されていますが、抽象化は機能します)。

init上記の例は、の代わりに呼び出しているため、混乱を招きますinitWithFrame。親クラスの指定された初期化子を呼び出す必要があります-この場合は、を使用しsuperます。

呼び出すイニシャライザー(この場合、はイニシャライザーを呼び出すとinit間違ったイニシャライザーを使用しています。その場合、再帰サイクルをエスケープすることはできません。

したがって、親で呼び出すメソッドを正確に選択することはできません。ただし、独自のinitメソッドを使用できます。

def initWithTitle(title)
  initWithFrame(CGRectZero)
  @title = title
  return self
end

私はこのメソッドを次のように書きます:

def initWithTitle(title)
  initWithFrame(CGRectZero).tap do
    @title = title
  end  # that way I never forget to return self
end
于 2013-02-02T18:44:31.800 に答える
0

私があなたを正しく理解しているなら、あなたはrubymotionであなた自身のカスタム初期化メソッドを作成したいが、それでも元のinitメソッドを呼び出したい。

私は頻繁にこのようなことをします:

#custom initializer
def initialize
 self.init # <--calls 'init' from parent

 #stuff happens here
end

superを呼び出す代わりに、initメソッドを呼び出すだけです。これは、オブジェクトが初期化に達するまでにすでに割り当てられているため、機能します。また、渡す変数がある場合は、初期化子と見なされるメソッドにそれらを渡します。

(編集:おそらく自己が必要です。)

于 2013-02-01T19:41:05.587 に答える