20

ARC の下で次のコードを想定します。

typedef void (^MyResponseHandler) (NSError *error);
@interface MyClass : NSObject
{
    MyResponseHandler _ivarResponseHandler;
}

- (void)myMethod:(MyResponseHandler)responseHandler
{
    _ivarResponseHandler = responseHandler;
    ...
}

質問: ivar に割り当てられると、ブロックは自動的にヒープにコピーされますか?

私の以前の質問は、 を介して割り当てられたときにコピーされることを暗示していました@property。しかし、今日、私は上記のコードを使用し、にEXC_BAD_ACCESS変更することで修正されたを受け取りました

_ivarResponseHandler = [responseHandler copy].

4

2 に答える 2

10

編集:私の以前の答えはおそらく間違っていました。

ARCドキュメントからのいくつかの選択された抜粋は次のように述べています:

3. 保持可能なオブジェクト ポインタ

保持オブジェクトポインタ(または保持ポインタ)は、保持オブジェクトポインタ型(保持型)の値である。保持可能なオブジェクト ポインターの型には、次の 3 種類があります。

  • ブロック ポインター (キャレット (^) 宣言子シジルを関数型に適用することによって形成されます)

4.2. セマンティクス

代入演算子を評価するときに代入が発生します。セマンティクスは修飾によって異なります。

  • __strong オブジェクトの場合、新しい指示先が最初に保持されます。次に、左辺値にプリミティブ セマンティクスが読み込まれます。3 番目に、新しい pointee がプリミティブ セマンティクスを使用して左辺値に格納されます。そして最後に、古い指先が解放されます。これはアトミックには実行されません。外部同期を使用して、同時ロードおよびストアに直面してもこれを安全にする必要があります。

4.4.1. オブジェクト

オブジェクトが保持可能なオブジェクト所有者型で宣言されているが、明示的な所有権修飾子がない場合、その型は __strong 修飾を持つように暗黙的に調整されます。

7.5. ブロック

__strong パラメーター変数の初期化または __weak 変数の読み取りの一部として行われる保持を除いて、これらのセマンティクスがブロック ポインター型の値を保持することを要求するときはいつでも、Block_copy の効果があります。オプティマイザーは、結果が呼び出しの引数としてのみ使用されていることを確認すると、そのようなコピーを削除することがあります。

したがって、オプティマイザーによっては、答えはおそらくだと思います。

于 2012-05-14T01:14:42.527 に答える
4

あなたの問題と解決策は、あなたの他の質問に対する私の答えがおそらく間違っていたことを示しています。私はそれをclang Objective-C Automatic Reference Counting documentationのセクション7.5の最後の段落に基づいていました:

__strongパラメーター変数の初期化または変数の読み取りの一部として行われる保持を除いて、__weakこれらのセマンティクスがブロックポインター型の値を保持することを要求するときはいつでも、Block_copy. オプティマイザーは、結果が呼び出しの引数としてのみ使用されていることを確認すると、そのようなコピーを削除することがあります。

「これらのセマンティクス」をドキュメント全体を意味するものとしましたが、「これらのセマンティクス」がセクション 7.5 のみを指す場合、ARCBlock_copyはブロックによってキャプチャされたブロックにのみ for を挿入します。

于 2012-05-04T17:23:23.407 に答える