UIImage(named:) 和 UIImage(imageLiteralResourceName:) 有什么区别?

What is the difference between UIImage(named:) and UIImage(imageLiteralResourceName:)?

Swift 3/iOS 10 在 UIImageimageLiteralResourceName:

上添加了一个新的初始值设定项
extension UIImage {

    required public convenience init(imageLiteralResourceName name: String)
}

这与 public init?(named name: String) 有何不同?我 named 是一个失败的初始化器,而 imageLiteralResourceName 会在无效的图像名称上崩溃。 imageLiteralResourceName 是否以安全换取性能?什么时候应该使用 imageLiteralResourceName 而不是 named

看着open-source implementation of UIKit,好像没什么区别:

extension UIImage : _ImageLiteralConvertible {
  private convenience init!(failableImageLiteral name: String) {
    self.init(named: name)
  }

  public required convenience init(imageLiteralResourceName name: String) {
    self.init(failableImageLiteral: name)
  }
}

public typealias _ImageLiteralType = UIImage

它所做的只是强制解包 init(named:).

的结果

它似乎只是 CompilerProtocols.swift 中发现的 _ImageLiteralConvertible 协议的一个实现:

public protocol _ImageLiteralConvertible {
  init(imageLiteralResourceName path: String)
}

AppKit也有类似的实现:

extension NSImage : _ImageLiteralConvertible {
  private convenience init!(failableImageLiteral name: String) {
    self.init(named: name)
  }

  public required convenience init(imageLiteralResourceName name: String) {
    self.init(failableImageLiteral: name)
  }
}

public typealias _ImageLiteralType = NSImage

这可能与添加到 Xcode 8 的新图像文字功能 (#imageLiteral) 有关,不应直接调用。