由闭包错误自我捕获

Posted

技术标签:

【中文标题】由闭包错误自我捕获【英文标题】:Self captured by a closure error 【发布时间】:2017-06-19 11:04:23 【问题描述】:
var myGroup = DispatchGroup()

class Place: NSObject, NSCoding 

// Properties
var placeCoordinate: CLLocation!
var placeName: String!

// Methods
required init(coder aDecoder: NSCoder) 
    self.placeCoordinate = aDecoder.decodeObject(forKey: "placeCoordinate") as! CLLocation
    self.placeName = aDecoder.decodeObject(forKey: "placeName") as! String


init(latitude: CLLocationDegrees, longitude: CLLocationDegrees) 
    myGroup.enter()
    self.placeCoordinate = CLLocation(latitude: latitude, longitude: longitude)
    CLGeocoder().reverseGeocodeLocation(self.placeCoordinate, completionHandler:  (placemarks, error) -> Void in
        if error != nil 
            self.placeName = "Unrecognized"
            print(error!)
         else 
            if let placemark = placemarks?[0] 
                self.placeName = (placemark.addressDictionary!["FormattedAddressLines"] as! [String])[1]
                myGroup.leave()
            
        
    )


func encode(with aCoder: NSCoder) 
    aCoder.encode(placeCoordinate, forKey: "placeCoordinate")
    aCoder.encode(placeName, forKey: "placeName")


如您所见,我已经构建了使用async 函数的此类。

我想将这个对象的数组保存在UserDefaults。我发现在 UserDefaults 中保存自定义对象是不可能的,所以现在我正在尝试使用 NSCoding

在上面的代码中我得到错误:

在所有成员初始化之前被闭包捕获

reverseGeocodeLocation函数行的构造函数中。

需要提及的是,在我添加 NSCoding 部分之前,以下代码有效。

【问题讨论】:

【参考方案1】:

closure 中使用[weak self] capture list 作为:

CLGeocoder().reverseGeocodeLocation(self.placeCoordinate, completionHandler: [weak self] (placemarks, error) -> Void in
            //...
        )

【讨论】:

你能解释一下它是什么吗? 为了避免retain循环,将self设为weak。由于 self 被闭包捕获,因此即使 self 被取消初始化,它也可能持有对 self 的引用,因此应用程序可能会崩溃。因此,为了避免使用对 self 的这种弱引用。有关弱引用的更多信息,请参阅:developer.apple.com/library/content/documentation/Swift/…

以上是关于由闭包错误自我捕获的主要内容,如果未能解决你的问题,请参考以下文章

错误:转义闭包捕获变异的“自我”参数

在闭包中引用属性需要明确的“自我”。使捕获语义明确

SwiftUI 转义闭包捕获变异的“自我”参数

为啥 Swift 闭包不捕获自我?

转义闭包捕获变异的“自我”参数,Firebase

获取 JSON,附加到数组:转义闭包捕获变异的“自我”参数