2012-01-07 8 views
3

クラス内で使用できるブロックが必要なので、インスタンス内のさまざまな方法で何度も再利用できます。自己にアクセスしてインスタンス全体で使用できるブロック

ブロックを自己参照できるようにします。

私はブロックが自分自身を保持することによって任意の厄介な保持サイクルを作成しないようにしたい。

これまでのところ私は困惑しています。どのメソッド定義の外にも.mでブロックを作成することができました。途中でブロックを再利用できましたが、自己にアクセスできませんでした。私はブロックを瓶に入れようとしましたが、私は何か間違ったことをしています。今はランダムなEXC_BAD_ACCESSを得ています。誰かがそれを単に行ごとに説明することはできますか?

+1

これまでに行ったことのいくつかのコードを表示できますか? – tobiasbayer

答えて

0

私はそれを理解しました。 MyClass.hで

:initメソッドで

typedef void (^DefaultFailureBlock)(); 

@property (copy) DefaultFailureBlock defaultFailureBlock; 

__block MyClass *selfReq = self; 
self.defaultFailureBlock = ^{ 
    //use selfReq instead of self in here. 
}; 

誤ってブロック内で自己を参照する場合興味深いことに、あなたが保持サイクルを持っている、との意志を分析します不平を言わないでください。私はそれが実際に割り当て解除されていることを証明するためにdeallocにNSLogを入れました。

[defaultFailureBlock release]を忘れないでください。 deallocでも...

+1

ブロック内の保持サイクルを避けるために、selfへの__weakリファレンスを使用してください。これらのARCベストプラクティスの「ブロック」セクションを参照してください。http://amattn.com/2011/12/07/arc_best_practices.html – isaac

1

は、以下のことを試してみてください。

typedef void (^MyBlock)(); 

@implementation MyClass 
{ 
    MyBlock block; 
} 

- (id) init 
{ 
    self = [super init]; 
    if (!self) 
     return nil; 

    __block MyClass* _self = self; 

    block = [^ { 
     [_self sendSomeMsg]; 
    } copy]; 
} 

__blockストレージタイプに注意してください。 thisを引用する: "関数レベルでは__block変数です。これらはブロック(および囲みスコープ)内で変更可能であり、参照するブロックがヒープにコピーされても保持されます。

+0

これは私が終わったものに近いです。私は[^ {[];}コピーと比較してより読みやすいと思うので、(コピー)と@propertyを純粋に使用します。 – jsd

1

このイディオムは、exc_bad_access(ARCコード)を削除するのに役立ちます。

// get a weak reference to self 
__weak id weakSelf = self; 
block = ^() 
{ 
    // now the block is executing so we get a strong reference to self 
    // (this prevents self from disappearing until the block is done executing) 
    id strongSelf = weakSelf; 
    if (strongSelf != nil) 
    { 
     // do whatever work you intended for this block 
    } 
}; 
+0

あなたは__weakの代わりに__blockを使いたいと思うようです。たぶん同じ意味ですが、__blockは意図を明示的にします。 – jsd

+0

ARCコードでは、__blockのセマンティクスが異なります。保持を妨げず、変数の値を変更する場合にのみ使用してください。 – Jano

関連する問題