Думаю, я хорошо разбираюсь в сильных и слабых ключевых словах, но не понимаю, как они используются в приведенном ниже коде. Этот код взят из SDWebImage от Olivier Poitrey и доступен на github. Я понимаю сильные и слабые ключевые слова, как описано здесь: Объяснение сильных и слабых хранилище в iOS5
В приведенном ниже коде ключевые слова __weak и __strong используются любопытным для меня образом. Это не отношения ребенок-родитель или образец делегирования, поскольку я привык видеть слабое использование. Однако я уверен, что этот шаблон используется часто, поскольку я видел его раньше в другом коде. Он устанавливает ссылку __weak перед блоком, который выполняется в другом потоке. Затем внутри блока слабая ссылка заменяется сильной ссылкой.
Я уверен, что это хороший и элегантный код, поэтому я пытаюсь его понять. Если «я» перестанет существовать до того, как блок запустится, слабая ссылка на себя будет обнулена. Когда блок запускается, сильная ссылка также будет установлена на ноль. Следовательно, он будет знать, что нужно завершить остальную часть операции, поскольку self больше не существует. Я правильно понял?
Что произойдет, если мы не будем использовать ключевые слова __weak и __strong? Что, если мы просто проверим внутри блока, является ли self == nil. Будет ли «я» никогда не равным нулю, поскольку блок копирует все дерево?
Может ли кто-нибудь помочь демистифицировать этот удивительный фрагмент кода? Может ли кто-нибудь подтвердить или опровергнуть мои предположения?
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock;
{
[self cancelCurrentImageLoad];
self.image = placeholder;
if (url)
{
__weak UIImageView *wself = self;
id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished)
{
__strong UIImageView *sself = wself;
if (!sself) return;
if (image)
{
sself.image = image;
[sself setNeedsLayout];
}
if (completedBlock && finished)
{
completedBlock(image, error, cacheType);
}
}];
objc_setAssociatedObject(self, &operationKey, operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
}