-->

Ambiguous use of 'sd_setImage(with:placeholder

2020-02-24 12:14发布

问题:

I am making the following call using SDWebImage on my imageView, which works fine with Swift 2 but gives an error with XCode 8 beta 5 compiling with Swift 3:

 imageView.sd_setImage(with:url, placeholderImage:placeholder, completed: {
    (image: UIImage?, error: Error?, cacheType: SDImageCacheType, imageURL: URL?) in
            ...
    });

The error is:

Ambiguous use of 'sd_setImage(with:placeholderImage:completed:)'

I suspect I have something wrong in the signature for the completed handler, but I can't figure out what the syntax should be. What am I missing?

回答1:

The Swift compiler translates the ObjC headers into Swift which leads to naming collisions:

UIImageView+WebCache.h:

o1) - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;

o2) - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;

Their only difference is the additional optionsparameter in o2.

Generated Swift declaration:

s1) open func sd_setImage(with url: URL!, placeholderImage placeholder: UIImage!, completed completedBlock: SDWebImage.SDWebImageCompletionBlock!)

s2) open func sd_setImage(with url: URL!, placeholderImage placeholder: UIImage!, options: SDWebImageOptions = [], completed completedBlock: SDWebImage.SDWebImageCompletionBlock!)

Because options was translated into an optional parameter (default assigned an empty array) calling s1 in Swift leads to an ambiguous use. Calling s2 could simply have the same implementation. When providing such methods in Swift code one would add the options parameter as optional in a single function implementation.

Workaround

As a workaround the options parameter could be set or o1 or o2 could be renamed temporarily until SDWebImage will be translated into Swift.



回答2:

Adding SDWebImageOptions to the method call fixes the issue:

imageView.sd_setImage(with: someUrl,
          placeholderImage: someImage,
                   options: [], 
                 completed: someCompletitionBlock)