2016-05-16 4 views
2

Я использую старую версию SDWebImage но получил аварию, как показано ниже:Почему в SDWebImage «сильная ссылка на UIImageView может вызвать сбой во вложенном блоке»?

0 libobjc.A.dylib      0x000000019671bbd0 objc_msgSend + 16 
1 UIKit        0x0000000189932eac -[UIView(Rendering) contentMode] + 316 
2 UIKit        0x00000001899320e0 -[UIImageView _canDrawContent] + 144 
3 UIKit        0x0000000189932bac -[UIImageView _updateState] + 36 
4 UIKit        0x0000000189932b6c +[UIView(Animation) performWithoutAnimation:] + 88 
5 UIKit        0x0000000189c6b340 -[UIImageView _updateImageViewForOldImage:newImage:] + 452 
6 UIKit        0x0000000189932590 -[UIImageView setImage:] + 320 
7 xxxx        0x0000000100927adc __85-[UIImageView(WebCache) setImageWithURL:placeholderImage:options:progress:completed:]_block_invoke + 100 

блока, где произошло крушение является:

 __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 setNeedsDisplay]; 
               [sself setNeedsLayout]; 
              } 
              if (completedBlock && finished) 
              { 
               completedBlock(image, error, cacheType); 
              } 
             }]; 

Тогда я нашел затруднительное положение SDWebImage, фиксацию комментарий:

Удален сильная ссылка на UIImageView, который вызывает сбой в вложенном блоке

Адрес commit. Единственным изменением было удаление сильной ссылки UIImageView в блоке.

The commit

Используйте сильные ссылки в блоке, чтобы сохранить консистенцию широко используется, но почему SDWebImage было это изменение. Почему это может привести к сбою? Если UIImageView вызовет сбой, что еще?

+0

Мое предположение заключалось в том, что IV был удален из иерархии представлений или каким-то другим способом был введен в состояние, когда он не мог рисовать изображение без сбоев. Удаление сильной ссылки предотвращает жизнь IV после того, как она попала в это недопустимое состояние. – Avi

+0

@Avi Звучит разумно. Но все же хотите получить точное объяснение, если UIImageView имеет такую ​​проблему, а что касается других? – feihu

+0

Что такое сообщение об ошибке, связано ли это с авто-макетом? – Wain

ответ

1

Какое это исправление будет работать, является условием гонки во время удаления и/или уничтожения вида, когда внутренние буферы визуализации освобождаются, но сохранение может быть применено вовремя для предотвращения освобождения. Затем, если что-то срабатывает при записи в те исчезнувшие буферы poof, вы получаете эту ошибку сегментации.

Теоретически эта проблема может быть встречена в любом месте, где непосредственно обращаются к исходным указателям, и их уничтожение недостаточно защищено. На практике код уровня UIKit вряд ли будет запущен в нем, кроме API-интерфейсов, основанных на UIImage, и я бы предположил, что это будет довольно эзотерическое условие гонки, чтобы быть осторожным, чтобы отменить все асинхронные обновления до начала просмотра, ; которые вы должны делать, чтобы избежать ненужной работы в любом случае.

+0

Спасибо за ответ, мы должны быть осторожны, чтобы использовать сильную ссылку для API на основе UIImage. – feihu

Смежные вопросы