【问题标题】:Swift computed property return valueSwift 计算属性返回值
【发布时间】:2018-02-03 09:13:25
【问题描述】:

我有一个计算属性,如果它失败,它应该返回一个对象或 nil。

var findRequest: Book {
    get {
        var foundRequest: Book!
        API.requestBook(book: bookRequest) { book in
            if book != nil {
                foundRequest = book!
            } else {
                print("Could not find book")
                foundRequest = nil
            }
        }
        return foundRequest
    }
}

当我运行代码时,我在返回 foundRequest 行上解包 Optional value 错误时意外发现 nil。看起来代码跳过了我的闭包函数并直接返回。

谢谢

【问题讨论】:

  • 也许请求是异步的

标签: ios swift variables computed-properties


【解决方案1】:

我有一个计算属性,如果它失败,它会返回一个对象或 nil。

那么你可能应该将其定义为:

var findRequest: Book? {
    // ...

(注意Book 后面的“?”)

此外,就像 Martin 在 cmets 中提到的那样,您的计算属性的 getter 应该立即返回一个值,但您正在执行看起来像异步调用来检索该值的操作。在调用完成处理程序之前,getter 本身会立即返回。访问该属性的一方无法获得 API 返回的实际值。

【讨论】:

  • 谢谢 - 那么此时函数调用会更好还是我仍然可以使用 CP?
  • 是的,但是一个接受完成处理程序的函数。在闭包被回调之前你不能做任何事情,这就是异步调用的重点。
【解决方案2】:

您的实施存在几个问题。首先,如果foundRequest 的值有可能是nil,则不应将foundRequest 定义为隐式展开的可选项。其次,您在异步函数API.requestBook 的完成处理程序之外返回值,因此您在foundRequest 获得值之前返回,因此您返回默认值nil,这将是强制的由于隐式解包的可选声明而解包,因此出现错误。

此外,您不应该在计算属性的 getter 内发出异步请求,因为计算属性应该立即返回值。

您应该完全更改您的实现,使 findRequest 成为在完成处理程序中返回 Book 类型值的函数。

func findRequest(bookRequest: URLRequest, completion: @escaping (Book?->Void)){
        API.requestBook(book: bookRequest) { book in
            if let book = book {
                completion(book)
            } else {
                print("Could not find book")
                completion(nil)
            }
        }
}

你可以这样调用函数:

findRequest(bookRequest: yourRequest, completion: { book in
    if let book = book {
        //use the returned value
    } else {
        print("Book not found")
    }
})

您可能需要将bookRequest 的类型从URLRequest 更改为需要输入参数book 的类型。

【讨论】:

  • 谢谢 - 不知道 CP 不会等到关闭完成。将重构。
猜你喜欢
  • 2019-02-14
  • 2018-06-30
  • 1970-01-01
  • 2018-09-19
  • 1970-01-01
  • 2021-02-16
  • 1970-01-01
  • 2018-07-15
  • 1970-01-01
相关资源
最近更新 更多