Как правильно избегать сохранения цикла при использовании блоков?

Как правильно добавить объекты в NSMutableArray, который строго определен свойством.

[tapBlockView setTapBlock:^(UIImage* image) {
   [self.myImageArray addObject:image]; // self retain cycle
}

Если я создам слабую ссылку что-то вроде

__weak NSMutableArray *array = self.myImageArray;
[tapBlockView setTapBlock:^(UIImage* image) {
    [array addObject:image]; // If I will do this then how will I update original Array ?
}

Я также пытался

__weak id weakSelf = self;
[tapBlockView setTapBlock:^(UIImage* image) {
    [weakSelf storeImageInaNewMethod:image]; // Calling SToreImageInaNewMethod
}

а также

-(void)storeImageInaNewMethod:(UIImage*)image {
   [self.myImageArray addObject:image]; // This again retaining cycle
}

Как правильно обновить исходный объект, определенный свойством?

4 ответа

Решение

Попробуйте комбинацию 2-го и 3-го.

__weak id weakSelf = self;
[tapBlockView setTapBlock:^(UIImage* image) {
    [weakSelf.myImageArray addObject:image];
}

После ответа Мэдди - это лекция WWDC 2012 года по GCD и асинхронному программированию:

__weak MyClass *weakSelf = self;

[tapBlockView setTapBlock:^(UIImage* image) {
    __strong MyClass *strongSelf = weakSelf;
    if(strongSelf) {
        [strongSelf.myImageArray addObject:image];
    }
}];

В вашем случае вам нужно только сослаться на массив, на который ссылается self, так:

NSMutableArray *array = self.myImageArray;
[tapBlockView setTapBlock:^(UIImage* image)
                          {
                             [array addObject:image]; // No cycle
                          }];

Работает нормально при условии, что self.myImageArray не возвращает разные ссылки на массив в разное время. Цикла нет: текущий объект ссылается на массив и блок, а блок, в свою очередь, ссылается на массив.

Если self.myImageArray возвращает разные ссылки на массив как разное время, а затем использовать слабую ссылку на selfтвой случай 3.

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

Другие вопросы по тегам