我试图从我班上声明的闭包中引用我的类中的属性。我无法从我的闭包中访问self,而且我假设self会在我的闭包内引用Class API。
我想声明一个闭包,我稍后将其用作传递给URLSession dataTask的参数(它在没有一个错误行的情况下工作)。我收到标题中列出的错误。
使用未解析的标识符'self'
我现在已经写了一整天了,我只是想把它作为一个沙箱,所以我完全期待一些批评。
class Api {
struct Location {
var name = String()
var author = String()
var averageRating: String?
var id = Int()
var lat = Double()
var lon = Double()
var type = String()
}
var locations = [Location]()
var doSomething = {(data: Data?, response: URLResponse?, error: Error?) -> Void in
if error != nil {
print(error!.localizedDescription)
} else {
do {
if let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String: Any] {
let myResult = json["results"] as! [[String: Any]]
var location : Location! = Location()
for jsonLocation in myResult {
if let name = jsonLocation["name"]{location.name = name as! String}
if let author = jsonLocation["author"]{location.author = author as! String}
if let id = jsonLocation["id"]{location.id = id as! Int}
if let lat = jsonLocation["lat"]{location.lat = lat as! Double}
if let lon = jsonLocation["lon"]{location.lon = lon as! Double}
if let type = jsonLocation["type"]{location.type = type as! String}
//ERROR IS HERE, Why does self not reference class API?
self.locations.append(location)
}
}
} catch {
print("error in JSONSerialization")
}
}
}
}
我找到了this,但这个例子不同,所以我不确定它是不是同一个错误,或者我不理解swift。
答案 0 :(得分:10)
Rahul的解释是正确的,但建议的答案有点不完整。
这是一个完整的解决方案:
将Rahul建议的doSomething
属性声明为lazy
。惰性存储属性是一个属性,其初始值在第一次使用之前不会计算。换句话说,在运行时调用doSomething属性之前不会评估此闭包,此时{G}保证存在self
。有关详细信息,请参阅Swift编程语言中的Lazy Stored Properties。
向doSomething
属性添加类型注释,以便编译器不必在编译时推断类型,显然它不能这样做,因为闭包包含self
。有关详细信息,请参阅Swift编程语言中的Type Safety and Type Inference。
所以完整的声明是:
...
lazy var doSomething: (Data?, URLResponse?, Error?) -> Void = { (data: Data?, response: URLResponse?, error: Error?) -> Void in
...
PS。欢迎来到Swift编程!这是一种很棒的语言,非常有趣。我希望你和我一样喜欢它。
答案 1 :(得分:3)
您无法访问self
,因为当您在闭包内部调用时它不可用,因为初始化尚未发生,因此编译器会给您错误。
修复将是用户lazy
var,因为这将推迟self
调用,因为只有在初始化后才会调用lazy var。
lazy var doSomething = { your closure goes here }
答案 2 :(得分:2)
我和你有同样的问题,我使用gcc
来解决它
这是一个简单的例子
我原来的代码是:
lazy var
在我使用class MyClass {
let callback:()->() = {
self.foo() // Compile error: Use of unresolved identifier "self"
}
func foo() {
print("bar")
}
}
的那一行编译错误
但我把它改为
self
解决了这个问题
参考文献:
https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html
http://mikebuss.com/2014/06/22/lazy-initialization-swift/
Shall we always use [unowned self] inside closure in Swift
答案 3 :(得分:0)
将此var locations = [Location]()
var locations : [Location]?
和var location : Location! = Location()
与self.locations = [Location]()
和self.locations.append(location)
与self.locations?.append(location)
你会好起来的!
懒惰变量是一个太复杂的概念无法掌握我猜,但你可以这样使用它:
lazy var locations:[Location] = {
let locations = Location()
return locations
}()