【问题标题】:Why can't swift infer the closure type为什么不能快速推断闭包类型
【发布时间】:2018-12-26 20:23:06
【问题描述】:

使用 Swift 的第一周,在 Xcode 10.1 上使用 Swift 4.2 新创建的项目),我是 following a tutorial on a how to make a photo gallery app 我对编译器错误感到震惊。

我的情况是这样,在自定义 ViewController 中继承自 UIViewController 并导入 UIKitPhotos。这个方法被 viewWillAppear 调用为 self.displayPhoto

self.photosAssetself.index 由 segue 上的前一个 viewController 设置。

func displayPhoto() {
    let imageManager = PHImageManager.default()
    var ID = imageManager.requestImage(
        for: self.photosAsset[self.index] as PHAsset,
        targetSize: PHImageManagerMaximumSize,
        contentMode: .aspectFit,
        options: nil,
        resultHandler: { (result:UIImage!, info:NSDictionary!) in
            self.imgView.image = result
        }
    )
}

Xcode 抱怨 无法在当前上下文中推断闭包类型 用于 resultHandler 中的闭包。有什么类型可以推断?

Looking at the documentation 看起来 resultHandler 有一个 void 返回类型:

【问题讨论】:

  • 只要不通过明确给出错误的类型来搞乱类型推断,就没有类型可以推断。
  • 感谢您的所有帮助,但为什么投反对票?
  • 好吧,你自己链接到文档,答案就在你面前。文档说UIImage?,你说UIImage! 文档说[AnyHashable : Any]?,你说NSDictionary! 我没有投反对票,但我明白为什么有人会投反对票。

标签: ios swift photosframework phimagemanager


【解决方案1】:

resultHandler 中,您应该使用(image, _) 而不是(result:UIImage!, info:NSDictionary!)

func displayPhoto() {
    let imageManager = PHImageManager.default()
    var ID = imageManager.requestImage(
        for: self.photosAsset[self.index] as PHAsset,
        targetSize: PHImageManagerMaximumSize,
        contentMode: .aspectFit,
        options: nil,
        resultHandler: { (image, _) in
            self.imgView.image = image
        }
    )
}

注意:要改进您的方法,您可能需要在options: 中设置PHImageRequestOptions

func displayPhoto() {
    let imageManager = PHImageManager.default()
    let requestOption = PHImageRequestOptions()
    requestOption.isSynchronous = true
    requestOption.deliveryMode = .highQualityFormat

    var ID = imageManager.requestImage(
        for: self.photosAsset[self.index] as PHAsset,
        targetSize: PHImageManagerMaximumSize,
        contentMode: .aspectFit,
        options: requestOption,
        resultHandler: { (image, _) in
            self.imgView.image = image
        }
    )
}

【讨论】:

    【解决方案2】:

    你可以用Dictonary代替NSDictionary,但是不需要声明handler的参数类型

    ... { result, info in
        ...
    }
    

    您也不必指定[AnyHashable : Any]? 类型的参数,因为您不需要它,只需在此处添加下划线_

    ... { image, _ in
        self.imgView.image = image
    }
    

    【讨论】:

      【解决方案3】:

      你自己打错了闭包。正确的类型是:

      @escaping (UIImage?, [AnyHashable : Any]?) -> Void
      

      你有:

      (result:UIImage!, info:NSDictionary!) in
      

      这是错误的。这对编译器非常不利!摆脱编译器的阻碍,它推断类型;它比你更清楚它们的优点。写

      result, info in
      

      一切都会好起来的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多