2016-05-04 32 views
0

Objective-Cの学習中です。メソッド参照を配列に格納して、配列をループしてメソッドを呼び出すことができます。私は、インタプリタ言語の背景から来ているとRubyのような言語では、次の配列内のオブジェクトメソッドへの参照を格納する(Objective-C)

NSMethodSignature *signature = [objectOne methodSignatureForSelector:@selector(methodOne)]; 
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 
[invocation setSelector:@selector(methodOne)]; 
[invocation setTarget:objectOne]; 


NSArray *methodArr = @[invocation]; 

for (int i = 0; i < [methodArr count]; i++) { 
    [methodArr[i] invoke]; 
} 

でこれを達成するためにNSInvocationを使用していた私が見つけた次

method_arr = [objectOne.method(:methodOne), objectTwo.method(:methodOne)] 

method_arr.each do |m| 
    m.call 
end 

最も近いもののような何かを行うことができます私が見つけたもう一つの方法は、メソッドを参照していないブロックを使用することなく、

NSArray *methodArr = @[^{ 
    [objectOne methodOne] 
}]; 

同様の結果を実現しますNSInvocationは少し退屈なようですこれを行うより良い方法があるのだろうかと思っていました。

答えて

0

私はブロックに行きます。配列を作成するときは、ブロック内の各メソッド呼び出しをラップし、ブロックを追加します。

NSArray *calls = @[ 
        ^{ [classInstance methodOne; }, 
        ^{ [classInstance methodTwo; }, 
        ^{ [classInstance methodThree; }, 
        ^{ [classInstance methodFour; }, 
       ]; 

このアプローチのメモリの問題に注意してください。特に基準サイクル。 classInstanceを弱い参照にします。

ブロックを呼び出すには、dispatch_block_tにキャストして呼び出します。

((dispatch_block_t)calls[0])(); 

アレイを入力すると、クリーナーを作成できます。

NSArray<dispatch_block_t> *calls = @[ 

今の呼び出しは、私は、アレイ内の文字列だけとなるだろう単に

calls[0](); 
0

です。メソッド名を配列に格納し、配列をループし、メソッド名文字列をセレクタにNSSelectorFromString()で変換し、オブジェクト/ sに対してperformSelector:を呼び出します。しかし、これは、そのセレクタが不明であるため

performSelectorが漏れを引き起こす可能性が言って不要な警告が表示されることがあり、これらのpragma

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Warc-performSelector-leaks" 
    [object performSelector: someSelector withObject: anotherObject]; 
#pragma clang diagnostic pop 
であなたの performSelector:コードをラップすることによって除去することができる

これはhereで説明されています

幸い、これは助けてくださいul!

関連する問題