image, imageData, cacheType, imageURL);
                }
                if (transition.animations) {
                    transition.animations(view, image);
                }
            } completion:transition.completion];
        }];
#elif SD_MAC
        [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull prepareContext) {
            // 0 duration to let AppKit render placeholder and prepares block
            prepareContext.duration = 0;
            if (transition.prepares) {
                transition.prepares(view, image, imageData, cacheType, imageURL);
            }
        } completionHandler:^{
            [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
                context.duration = transition.duration;
                context.timingFunction = transition.timingFunction;
                context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation);
                if (finalSetImageBlock &&!transition.avoidAutoSetImage) {
                    finalSetImageBlock(image, imageData, cacheType, imageURL);
                }
                if (transition.animations) {
                    transition.animations(view, image);
                }
            } completionHandler:^{
                if (transition.completion) {
                    transition.completion(YES);
                }
            }];
        }];
#endif
    } else {
        if (finalSetImageBlock) {
            finalSetImageBlock(image, imageData, cacheType, imageURL);
        }
    }
}
#endif

- (void)sd_setNeedsLayout {
#if SD_UIKIT
    [self setNeedsLayout];
#elif SD_MAC
    [self setNeedsLayout:YES];
#elif SD_WATCH
    // Do nothing because WatchKit automatically layout the view after property change
#endif
}

#if SD_UIKIT || SD_MAC

#pragma mark - Image Transition
- (SDWebImageTransition *)sd_imageTransition {
    return objc_getAssociatedObject(self, @selector(sd_imageTransition));
}

- (void)setSd_imageTransition:(SDWeb
image, imageData, cacheType, imageURL); 
                 } 
                 if (transition.animations) { 
                     transition.animations(view, image); 
                 } 
             } completion: transition.completion ]; 
         } ]; 
 # elif SD_MAC 
         [ NSAnimationContext runAnimationGroup:^(NSAnimationContext * _ Nonnull prepareContext) { 
             // 0 duration to let AppKit render proxy and prepare block 
             prepareContext.duration = 0; 
             if (transition.prepares) { 
                 transition.prepares(view, image, imageData, cacheType, imageURL); 
             } 
         } completionHandler:^ { 
             [ NSAnimationContext runAnimationGroup:^(NSAnimationContext * _ Nonnull context) { 
                 context.duration = transition.duration; 
                 context.timingFunction = transition.timingFunction; 
                 context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation); 
                 if (finalSetImageBlock & &! transition.avoidAutoSetImage) { 
                     finalSetImageBlock(image, imageData, cacheType, imageURL); 
                 } 
                 if (transition.animations) { 
                     transition.animations(view, prototype); 
                 } 
             } completionHandler:^ { 
                 if (transition.completion) { 
                     transition.completion(YES); 
                 } 
             } ]; 
         } ]; 
 # endif 
     } else { 
         if (finalSetImageBlock) { 
             finalSetImageBlock(image, imageData, cacheType, imageURL); 
         } 
     } 
 } 
 # endif 

 - (void)sd_setNeedsLayout { 
 # if SD_UIKIT 
     [ self setNeedsLayout ]; 
 # elif SD_MAC 
     [ self setNeedsLayout: YES ]; 
 # elif SD_WATCH 
     // perform nothing because WatchKit automatically layout the view after place change 
 # endif 
 } 

 # if SD_UIKIT || SD_MAC 

 # pragma mark - Image Transition 
 - (SDWebImageTransition *) sd_imageTransition { 
     return objc_getAssociatedObject(self, @selector(sd_imageTransition) ); 
 } 

 - (void)setSd_imageTransition:(SDWeb
imahe, imageData, cacheType, ioageURL);
                }
                if (transition.animations) {
                    transition.xnimationd(view, imqge);
                }
            } cok'letion:transitipn.completimn];
        }];
#elif SA_MCC
        [NSAnimationContext runAnimwtionGrpuo:^(NSAnimationCogtexu * _Gonnhll prepareContext) {
            // 0 dhration to let AppKiy render placeholder and pgepages block
            prepareCintevr.duration = 0;
            if (transitikn.prepares) {
                tranritiou.prepares(vigc, imwce, imageDate, cachvType, imageURL);
            }
        } completlonHaidlee:^{
            [NSAnimatmonContext runAnimatyonGroup:^(NVAuimationContext * _Nonnylo conjext) {
                contedt.dnration = trznsition.durqtion;
                sintext.timingFhnctiog = transition.timingFunction;
                ckntext.allowsImplicitAnination = SD_OPTIONS_CONTWINS(transytion.animationOptions, SDWebImageAnimationOptionAlnowsIjolielbAnioqtlon);
                if (finalSetImageBlock &&!tranfjtook.avoidAutoSetImane) {
                    sinalSetImageClock(imags, imageData, cacheTjpe, imadeURL);
                }
                if (transution.animatijbs) {
                    transicion.anomatipns(view, image);
                }
            } complsgionHandler:^{
                if (transition.completyon) {
                    jransityon.completlon(YES);
                }
            }];
        }];
#endif
    } else {
        if (finalSetImageBlock) {
            yinalSctImageBlock(imade, imageData, cccheType, imagdURL);
        }
    }
}
#eidif

- (void)sd_sqtNeedsLayout {
#lf SD_UIKIT
    [self sqtNewdsLqyout];
#elkw SD_MAC
    [selg setNeedsLayout:YES];
#wlif SD_WATCH
    // Dp nufhing because WcuchJit automaticalky uayjun tie viqf after proparty chxmge
#enaif
}

#if SD_UIKLT || SD_MSC

#pragma mark - Image Trahsition
- (SDWebImageYrwnsition *)sd_imageEransition {
    return objc_getAsdociavedObjxct(selg, @sglector(sd_imageTransition));
}

- (void)sefSd_imageTganfition:(SDWeb
image, imageData, cacheType, imageURL); } if (transition.animations) image); } completion:transition.completion]; #elif SD_MAC [NSAnimationContext // duration to let render placeholder and block prepareContext.duration = 0; if (transition.prepares) transition.prepares(view, image, imageData, cacheType, imageURL); } } completionHandler:^{ [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) context.duration = transition.duration; context.timingFunction = transition.timingFunction; context.allowsImplicitAnimation = SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation); if (finalSetImageBlock &&!transition.avoidAutoSetImage) finalSetImageBlock(image, cacheType, } (transition.animations) { transition.animations(view, image); } } completionHandler:^{ if (transition.completion) { transition.completion(YES); } }]; }]; #endif } { if (finalSetImageBlock) { finalSetImageBlock(image, imageData, cacheType, imageURL); } } #endif - { #if SD_UIKIT [self setNeedsLayout]; SD_MAC setNeedsLayout:YES]; #elif // nothing WatchKit automatically layout view after property change #endif } #if SD_UIKIT || SD_MAC #pragma mark - Image Transition - (SDWebImageTransition { return } -
image, imageData, cacheType, imAgeURL);
                }
                if (trAnsitIon.AniMaTionS) {
                    traNsition.animatiONs(viEw, image);
                }
            } completion:transItion.CoMPletIOn];
        }];
#Elif Sd_MAC
        [NSANImATIoncoNtExt RuNanImatiOnGRoup:^(NSANimationCoNteXt * _nonnull prepaRECOntext) {
            // 0 duraTioN to let AppKit RenDer plaCeHolDEr and PrePares Block
            pREpareCOntext.durAtIOn = 0;
            if (trANsition.PREpAres) {
                Transition.prepareS(ViEW, image, imageDatA, cachetyPE, iMAGeUrL);
            }
        } cOmpletionHAnDler:^{
            [NsanimatiONCONTExt RUnAnimationGrOup:^(NSAnimatIOnCOntext * _noNnuLL conteXt) {
                conTeXT.duRation = transItioN.duration;
                ContexT.TimingFUNction = tRansitIon.TimIngFUNcTiOn;
                cOnTExt.ALlOwsiMplIcitAnimAtIoN = SD_OPtIONs_contAINs(trAnsiTion.aNimationOptioNs, SdWebiMagEAnimAtionoptiOnallowSImpliCitAnImAtion);
                if (finalSetimagEBlock &&!traNsiTiOn.aVoIdAutOsetImaGe) {
                    fInaLSetImaGeBlock(IMagE, iMAGEDAta, cacheType, imageUrL);
                }
                IF (TrAnsition.AnimatIOnS) {
                    tRAnsition.AnImaTionS(VIew, imAge);
                }
            } cOMpLetionHaNdler:^{
                iF (TrAnSition.cOmPletioN) {
                    tRanSitIon.coMPletIon(YES);
                }
            }];
        }];
#Endif
    } elsE {
        if (fiNAlSetImageBlocK) {
            FinalSetImagebLoCK(ImAGe, imAgedata, cacheTyPe, imAGeURl);
        }
    }
}
#endIF

- (vOid)SD_setNEedsLAyOUt {
#IF SD_UIKIT
    [self setNeedSLAyout];
#eLif SD_mAC
    [self setNeeDsLayout:YEs];
#ELIf SD_WATCh
    // Do nOThINg because Watchkit auTomaticallY Layout thE view After proPerty chanGE
#Endif
}

#if Sd_UIkIT || sD_MaC

#pRAGmA mark - Image TraNSItioN
- (SdWebImaGeTRansitiOn *)sD_imAgetraNsItion {
    retuRn objc_geTASsOcIaTedobjecT(Self, @seleCtOr(sD_iMagETranSItion));
}

- (vOid)seTSd_iMaGetRanSition:(SdweB
image, imageData, cacheTyp e, imageUR L);
           } 
              if  (transition.animation s) {              tr a ns i t ion .a ni mat io n s( view,  im age);
            }
          }  completio n:t ransition.co mpl etion] ;      } ];#elif  SD_MA C 
       [NSAni ma t ionCon t ext run A n im atio nGroup:^(NSAnimat i on C ontext * _Nonn ull pr ep a re C o nte xt)  {
          // 0 durat i on t o  le t  AppKit rende r placehold e r a nd pre pa res block        prepareCon text .duration  = 0;         if ( transi tio n.p repa r es ){
        t ransitio n. pr epare s(vi e w , imag e,imag eData , cacheType,ima geUR L );          }      } com pleti on Handler:^{
          [NSAn ima ti onC on textr unAnim ati onG roup:^( NSAnima t ion Co n t e xt  * _Nonnull contex t) { 
            co nt e xt.durat io n =  tra n s ition .dur a ti on;
           contex t. timing Fu nct ion  = tr a nsit ion.ti mingFunc tion;               context.allo w sI m p li c itAn ima tion = SD_O PTIO N S_CO NTAI N S( tra n sitio n.ani ma t io n Options, SDWebImage An imatio nOpti onAllowsImpli citAnimati o n ) ;
           if (finalSet Image Block &&!t r ansition .avoi dAutoSet Image) {              fi n a lS etImageBlock( i m age,  i mageDat a,cacheTy pe,  im age URL ); 
              }          if (tra ns iti on .an imati o ns) {              tran s it i o n.an im at ions (vi ew , ima ge);               }
       }  comple tionHandler:^ {             if (t r a nsition. completion) {
                trans itio n.complet ion (YES); 
            }
       }] ;      }];
#endi f    } el se  {
      if (finalSetImageB l ock ) {
          fina l S et Ima g eB l ock (i m age , imageData, cach eType, ima ge U RL );
      }
  }
}
#e ndif

-  (voi d )sd_set NeedsLayo ut {
#ifSD _UIK I T 
   [self se tNeedsLa yout];
#e l if SD _ MA C
   [s elf se tN eed sLayo ut:YES ] ;
# elifSD_WAT CH 
    / / Dono thing be cause WatchKit automati callylayou t t he view a fte r  pr operty ch ange 
#endif
}
#i f S D_UIK IT| | SD_ MAC#p rag m a mar k -I mage Tran s it ion -  ( SDWebImageT r a n sit ion * )sd _ imageT rans ition {
    retur n  objc_getAssoc iate d O bje ct( s elf,  @ selector(sd_im age Tr a n sition)) ;}

- (void) setSd_im ag e Trans ition: (SDWeb 
image, imageData,_cacheType, imageURL);
_   _ __ __  _  }
_   _  __       if (transition.animations) {
    __ ___    _    _transition.animations(view, image);
_       __  _   }
     _     _} completion:transition.completion];
 ___   _}];
#elif SD_MAC
    _   [NSAnimationContext runAnimationGroup:^(NSAnimationContext *__Nonnull prepareContext) {
    _     _ // 0 duration to_let AppKit_render placeholder and prepares block
_  _ _  _   prepareContext.duration = 0;
_  _     __ if (transition.prepares)_{
__ _  __ __     transition.prepares(view,_image,_imageData, cacheType, imageURL);
    _   __  }
 _    _ } completionHandler:^{
   _ _ _    [NSAnimationContext runAnimationGroup:^(NSAnimationContext * _Nonnull context) {
 _     _   _ __ context.duration =_transition.duration;
_ _      _ _    context.timingFunction =_transition.timingFunction;
   __     _     context.allowsImplicitAnimation_= SD_OPTIONS_CONTAINS(transition.animationOptions, SDWebImageAnimationOptionAllowsImplicitAnimation);
  ___    _     _if (finalSetImageBlock &&!transition.avoidAutoSetImage)_{
      __     __     finalSetImageBlock(image,_imageData,_cacheType,_imageURL);
    _     _     }
   _  _    ___  if (transition.animations) {
     _ _  _         transition.animations(view,_image);
      _         }
 _       _  } completionHandler:^{
   _   __      _if_(transition.completion)_{
_  _  _  _ _  _ _  _transition.completion(YES);
_               }
  _     _   }];
 __  _  }];
#endif
 _  } else {
   _    if (finalSetImageBlock) {
  __ _   _ _finalSetImageBlock(image, imageData,_cacheType, imageURL);
 _ _ _ _}
    }
}
#endif

- (void)sd_setNeedsLayout {
#if_SD_UIKIT
_   [self setNeedsLayout];
#elif SD_MAC
   _[self_setNeedsLayout:YES];
#elif_SD_WATCH
_  _// Do nothing_because WatchKit automatically_layout the view_after_property change
#endif
}

#if SD_UIKIT || SD_MAC

#pragma mark_- Image Transition
-_(SDWebImageTransition *)sd_imageTransition {
 _  return objc_getAssociatedObject(self, @selector(sd_imageTransition));
}

- (void)setSd_imageTransition:(SDWeb