2016-05-16 5 views
2

Ich verwende eine ältere Version von SDWebImage aber einen Absturz wie unten erhalten:Warum in SDWebImage "starker Verweis auf UIImageView möglicherweise einen Absturz im verschachtelten Block verursachen"?

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 

Der Block, in dem der Unfall passiert ist:

 __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); 
              } 
             }]; 

Dann fand ich ein Update von SDWebImage, die verpflichten Kommentar ist:

entfernt starken Bezug auf UIImageView, die einen Absturz in dem verschachtelten Block verursacht wurden

Hier ist die commit. Die einzige Änderung war das Entfernen der starken Referenz des UIImageView im Block.

The commit

Verwenden starke Referenz im Block die Konsistenz zu halten, ist weit verbreitet, aber warum SDWebImage diese Änderung hatte. Warum könnte dies einen Absturz verursachen? Wenn UIImageView einen Absturz verursachen würde, was sonst würde?

+0

Meine Vermutung wäre, dass die IV aus der Ansichtshierarchie entfernt wurde oder auf andere Weise in einen Zustand versetzt wurde, in dem sie das Bild nicht ohne Absturz zeichnen konnte. Das Entfernen der starken Referenz verhindert, dass die IV aktiv wird, nachdem sie in diesen ungültigen Zustand gelangt ist. – Avi

+0

@Avi Klingt vernünftig. Aber immer noch eine genaue Erklärung, wenn UIImageView diese Art von Problem hat, was ist mit anderen? – feihu

+0

Was ist die Ausnahmebedingungsnachricht, ist es Auto-Layout verwandt? – Wain

Antwort

1

Dieser Fix würde eine Racebedingung beim Entfernen und/oder Löschen von Ansichten bewirken, bei der interne Rendering-Puffer freigegeben werden, aber die Retain-Funktion kann rechtzeitig angewendet werden, um eine Freigabe zu verhindern. Wenn dann etwas auf diese jetzt verschwundenen Puffer poof auslöst, erhalten Sie diesen Segmentierungsfehler.

Theoretisch könnte dieses Problem überall dort auftreten, wo auf rohe Zeiger direkt zugegriffen wird und ihre Zerstörung nicht ausreichend geschützt ist. In der Praxis ist es unwahrscheinlich, dass UIKit-Level-Code irgendwo anders als auf UImage-basierten APIs läuft, und ich würde mir vorstellen, dass es eine ziemlich esoterische Race-Bedingung wäre, alle asynchronen Updates vor dem Start des Teardowns abzubrechen ; was Sie tun sollten, um unnötige Arbeit zu vermeiden.

+0

Danke für die Antwort, wir sollten vorsichtig sein, starke Referenz für UIImage-basierte APIs zu verwenden. – feihu

Verwandte Themen