2012-11-13 4 views
5

オブジェクトパラメータを取るObjective-Cメソッドがあり、そのメソッドがブロックを使って内部的に処理を行っている場合、そのオブジェクトをブロック内から変更する方法はありますか?ブロック内のObjCメソッドのパラメータを変更するにはどうすればよいですか?

ブロックは、ブロック内で変数を参照して変数を親スコープから取得し、デフォルトでコピーされることは理解しています。そして、もし私が周囲のオブジェクトのコピーで作業するのではなく修正することができたいなら、その宣言に__blockという接頭辞を付けることができますが、私はそれを自分で宣言していないのでメソッドパラメータではできません。例えば

:あなたがキャプチャについて言う何

- (void)doWorkWithString:(NSString *)someString 
{ 
    [NSFoo doAwesomeClassMethodWithBlock:^{ 
     // How can I modify someString here directly? 
     // By just changing someString, I'm changing the captured copy 
    }]; 
} 
+0

私はドキュメントを調べるのが面倒ですが、ブロックへのキャプチャされた変数はコピーされているとは思いません。オブジェクトはコピーを実装しないかもしれないので、それは非常に驚くべきことです。 __blockが指定されていない場合、オブジェクトはブロックによって保持されます。ブロック内では、オブジェクトポインタはどこにもありませんので、あなたの質問に答えるために、好きなように修正することができます。 * IF * __blockが提供されていない変数に書き込むことはできません。 __blockでマークされた変数はブロックによって保持されないので、注意してください。うまくいけばそれはある意味があります。 –

+0

@darren:ブロックへの非_ブロック変数*がコピーされます。しかし、変数の値は決してオブジェクトではありません。 *オブジェクトポインタ*のみを持つことができます。つまり、ブロックがオブジェクトポインタを取得すると、ポインタがコピーされます。これは、オブジェクトのコピーとはまったく関係ありません。 – newacct

+0

「オブジェクトパラメータ」と言ったとき、私は「オブジェクトポインタ」パラメータを意味しました。例えばNSString *インスタンスを渡します。 –

答えて

1

が正しいです。おそらくあなたがしたいことは、ブロックの主語であるべきオブジェクトを引数として渡すことです.C関数を呼び出す場合と同じです。だから

void (^ someBlock)(NSString *) = 
    ^(NSString *someString) 
    { 
     NSLog(@"length is %d", [someString length]); 
    }; 

... 

someBlock(@"String 1"); 
someBlock(@"A second string"); 
1

私は上記のコメントが非常に混乱していたことに気付きました。うまくいけば、次は私が言おうとしたものまでクリア:

- (void)yourMethod:(Foo *)parameterFoo 
{ 
    __block Foo *blockVariable = [Foo someFoo]; 
    Foo *capturedVariable = [Foo anotherFoo]; 

    void(^doWorkBlock)(Foo *bp) = ^(Foo *bp){ 
     // If your block accesses a scoped variable that is not marked with __block, it will 
     // retain it, so here capturedVariable and bp would be retained by the block 
     capturedVariable.aProperty = 5.0; 
     bp.aProperty = 10.0; 

     // As you can see, you can modify the objects all you like.   
     // What you cannot do is assign something to capturedVariable or bp because they 
     // were not marked as __block 
     // WONT WORK 
     capturedVariable = [Foo new]; 

     // However, you can write to blockVariable because it is marked as __block 
     // WORKS 
     blockVariable = [Foo new]; 
     // Remember, though that the block will not retain this variable itself because 
     // of the __block 
    }; 

    // Note, it's weird for the block to take a parameter since it could just access the 
    // variable directly. This just serves to show how a block would handle a parameter. 
    doWorkBlock(parameterFoo); 
} 
2

すべての

まず「オブジェクトパラメータを取ること」、あなたはほぼ確実にあなたは、パラメータまたは変数を持つことができないという事実によって混乱していますオブジェクトタイプのオブジェクトへのポインタのみを持つことができます。したがって、ブロックによって取り込まれた変数__blockはブロックによってコピーされます。しかし、ここでの変数は、 "オブジェクト"ではなく、プリミティブまたはオブジェクトポインタです。

オブジェクトポインタが指すオブジェクトを変更するだけで、ポインタを変更して別のオブジェクトを指すことを必要としない場合は、変数を変更していません。そして変数を変更していないので、この "変数のコピー"と__blockのものは完全に無関係です。

関連する問題