可以访问self并在整个实例中使用的块

时间:2012-01-07 21:06:48

标签: objective-c objective-c-blocks

我想要一个在整个类中都可用的块,因此它可以通过实例中的不同方法重复使用多次。

我希望该块能够引用自我。

我希望通过保留self来阻止块创建任何讨厌的保留周期。

到目前为止,我很难过。我设法在任何方法定义之外的.m中创建块,这让我中途 - 我可以在任何地方重用块,但我无法访问自己。我尝试将块放入ivar但我在那里做错了,现在我得到随机的EXC_BAD_ACCESS。有人可以一行一行解释吗?

3 个答案:

答案 0 :(得分: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变量。这些变量在块(和封闭范围)内是可变的,并且如果任何引用块被复制到堆中,则会保留。”

答案 1 :(得分: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
    }
};

答案 2 :(得分:0)

我明白了。

在MyClass.h中:

typedef void (^DefaultFailureBlock)();

@property (copy) DefaultFailureBlock defaultFailureBlock;

在init方法中:

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

有趣的是,如果你不小心在块内引用了self,你将有一个保留周期,Analyze不会抱怨。我在一个dealloc中放了一个NSLog来证明它实际上是被释放的,而且它是。

哦,别忘了[defaultFailureBlock release];在dealloc中......