美文网首页Swift日更
[iOS] Swift调用SDWebImage找不到方法没有自动

[iOS] Swift调用SDWebImage找不到方法没有自动

作者: BudSwift | 来源:发表于2019-05-24 01:44 被阅读0次

测试环境: Xcode 10.1 Swift 4.2

如果在 OC 和 Swift 混编的项目中使用了 SDWebImage,那么在 Swift 文件中 imageView 设置网络图片时没有像 OC 中那么自然和顺利,先看 OC:

// OC
[imageView sd_setImageWithURL:someURL placeholderImage:somePlaceholder];

自动完成很自然顺畅:


OC 调用 SDWebImage 的自动完成情况

然而,Swift 就没有那么好可以自动完成了,同样的尝试:

Swift 调用 SDWebImage 的自动完成情况
通过查找方法的源头,从 SDWebImage 的 UIImageView + WebCache.h 的源代码中可以看到一个关键词 NS_REFINED_FOR_SWIFT,如下:
- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder NS_REFINED_FOR_SWIFT;

这个方法声明后面紧跟的是 NS_REFINED_FOR_SWIFT 系统的宏定义:

// Foundation/NSObjcRuntime.h
#define NS_REFINED_FOR_SWIFT CF_REFINED_FOR_SWIFT

单词 refine 的含义是提炼,顾名思义是只这个函数是从其他函数中提炼而来,由此可以发现 UIImageView+WebCache 中的其他函数也有同样的定义:

- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                   options:(SDWebImageOptions)options NS_REFINED_FOR_SWIFT;

- (void)sd_setImageWithURL:(nullable NSURL *)url
          placeholderImage:(nullable UIImage *)placeholder
                 completed:(nullable SDExternalCompletionBlock)completedBlock NS_REFINED_FOR_SWIFT;

进入 .m 查看它们的实现,就不难得出结论:这些方法都是由一个更多参数的 sd_setImageWithURL:placeholderImage:options:progress:completed: 提炼而来,其本质是在内部提供了这个多参数函数一些默认参数。

@implementation UIImageView (WebCache)

- (void)sd_setImageWithURL:(nullable NSURL *)url {
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}

- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
}

- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
}

- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
    [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
}

- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
    [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
}

- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
    [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
}

....
@end

那么回到 Swift 的调用,由于 Swift 函数支持默认参数的特性,标记有 NS_REFINED_FOR_SWIFT 的 OC 方法到了 Swift 中就由对应的带有默参数的多参数函数来实现了。因此 Swift 实际调用时先调用多参数函数:

extension UIImageView {
    func sd_setImageWithURL(_ URL?, 
            placeholderImage: UIImage? = nil, 
            options: [SDWebImageOptions] = [], 
            completed: SDExternalCompletionBlock? = nil)
            { ... }
}

直接调用此函数,方式一:

func test() {
    let imageView = UIImageView()
    let url = URL(string: "https://qq.com")
    let placeholder = UIImage(named: "image")
    imageView.sd_setImage(with: url,
                       placeholderImage: placeholder,
                        options: [], 
                        completed: nil)
}

再结合默认参数特性,将不需要的默认参数直接删除即可,方式二:


func test() {
    let imageView = UIImageView()
    let url = URL(string: "https://qq.com")
    let placeholder = UIImage(named: "image")
    imageView.sd_setImage(with: url, placeholderImage: placeholder)
}

更多的混编使用的宏

NS_SWIFT_NAME: 用来给一个 OC 函数、类型等一个 Swift 名字

#define NS_SWIFT_NAME(_name) CF_SWIFT_NAME(_name)

反之 Swift 的类型可以在 OC 调用时重命名,使用 @objc(renamed) 语法

@objc(MBPlacemark)
open class Placemark: NSObject, Codable {
....
}

加个微信,随时联系 😆

相关文章

网友评论

    本文标题:[iOS] Swift调用SDWebImage找不到方法没有自动

    本文链接:https://www.haomeiwen.com/subject/xrqwzqtx.html