Как сохранить сильную ссылку внутри блока без сохранения цикла

У меня есть блок, прикрепленный к кнопке (используя эту категорию):

__unsafe_unretained typeof(UIImage) *weakPic = originalPic;
[button addEventHandler:^{
    switch (state) {
    case state1:
        {
           UIViewController *vc = //some VC
           vc.pic = weakPic; // weakPic is nil at this point
                             // putting originalPic here would solve my problem
                             // but then I would have a retain cycle


        }  

    case state2:
        {
          // other stuff
        }
    }

}];

действие, связанное с кнопкой, зависит от состояния.

Вот проблема: я должен сохранить выше __unsafe_unretained, чтобы избежать цикла сохранения. Однако этот код вызывается в точке, где originalPic = nil.. и поэтому, когда я назначаю weakPic в vc.pic, я назначаю ему значение nil. Если я заменил weakPic на просто originalPic, тогда он отлично работает. (originalPic будет иметь обновленное значение), но затем я получаю цикл сохранения. Идеи?

Ответ 1

Не зная больше о вашем коде, я предлагаю вам подумать о том, чтобы объявить слабый сам и реализовать аксессуар на себе.

//the accessor
-(UIImage*)pic{
    return originalPic;
}

-(void)someSetupMethod{
    __weak id weakSelf = self;

    [button addEventHandler:^{
        switch (state) {
        case state1:
            {
               UIViewController *vc = //some VC
               vc.pic = [weakSelf pic]; // if weakself is nil at this point, then
                                        // originalPic is likely invalid


            }  

        case state2:
            {
              // other stuff
            }
        }

    }];
}

Это не может быть слабый, вы хотите, но какой-то другой объект. В этом случае просто объявляйте, что другой объект является слабым, если вы можете быть относительно уверенным, что он будет существовать дольше или длиннее кнопки.

Ответ 2

Вы также можете захотеть объявить его переменной __block. Ключевое слово __block предотвращает создание копии объекта внутри блока.

Смотрите этот поток для лучшего объяснения ссылок __weak и __block.