Блок, который может получить доступ к себе и использоваться в течение всего экземпляра - PullRequest
3 голосов
/ 08 января 2012

Я хочу, чтобы блок был доступен во всем классе, чтобы его можно было многократно использовать различными методами в экземпляре.

Я хочу, чтобы этот блок мог ссылаться на себя.

Я хочу, чтобы блок не создавал неприятных циклов сохранения, сохраняя себя.

Пока я в тупике. Мне удалось создать блок в .m вне определения любого метода, и это дало мне частичку - я мог использовать блок везде, но не мог получить доступ к себе. Я попытался поместить блок в ivar, но я делаю что-то не так, и теперь я получаю случайный EXC_BAD_ACCESS. Может кто-нибудь объяснить это просто, строка за строкой?

Ответы [ 3 ]

1 голос
/ 08 января 2012

Эта идиома может помочь вам удалить 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
    }
};
1 голос
/ 08 января 2012

Попробуйте следующее:

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 голосов
/ 08 января 2012

Я понял это.

В MyClass.h:

typedef void (^DefaultFailureBlock)();

@property (copy) DefaultFailureBlock defaultFailureBlock;

в методе init:

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

Интересно, что если вы случайно ссылаетесь на себя внутри блока, у вас будет цикл сохранения, и анализ не будет жаловаться. Я поместил NSLog в dealloc, чтобы доказать, что он действительно отменен, и это так.

Да, и не забудьте [релиз defaultFailureBlock]; в деаллоке тоже ...

...