在@objc标记的Swift点击函数中初始化CLPlacemark触发EXC_BAD_ACCESS错误
解决CLPlacemark初始化引发的EXC_BAD_ACCESS错误
嘿,我一眼就揪出问题所在了——你直接调用CLPlacemark()的无参初始化器是完全错误的!CLPlacemark这个类根本不支持这种初始化方式,手动创建未完全初始化的实例,后续操作必然会触发内存访问错误。
为什么会出错?
CLPlacemark是Core Location用来封装地理信息的核心类,它内部包含了大量依赖系统初始化的属性(比如地址详情、坐标关联的区域信息等)。直接用空初始化器创建的实例,这些关键属性都处于未初始化状态,当你后续尝试访问它们时,就会触发EXC_BAD_ACCESS这种内存错误。
正确的做法
你需要通过Core Location框架提供的合法途径来创建CLPlacemark实例,这里给你两种常用的方案:
方案1:通过反向地理编码获取(最常用场景)
如果你的需求是根据点击的坐标获取对应的地址信息,用CLGeocoder的反向地理编码接口是标准做法:
@objc func handleTap(sender: UITapGestureRecognizer) { switch sender.state { case .ended: let tapLocation = sender.location(in: mapView) let coordinate = mapView.convert(tapLocation, toCoordinateFrom: mapView) let tapLocation = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) let geocoder = CLGeocoder() geocoder.reverseGeocodeLocation(tapLocation) { [weak self] placemarks, error in guard let self = self, error == nil, let targetPlacemark = placemarks?.first else { // 处理错误或无结果的情况,比如提示用户无法获取地址 return } // 这里使用合法创建的targetPlacemark进行后续操作 print("点击位置的城市:\(targetPlacemark.locality ?? "未知")") } default: break } }
方案2:用指定初始化器手动构建(自定义场景)
如果你需要手动创建一个包含特定信息的CLPlacemark实例,可以使用它的指定初始化器(注意参数都要合法传入):
@objc func handleTap(sender: UITapGestureRecognizer) { switch sender.state { case .ended: let tapLocation = sender.location(in: mapView) let coordinate = mapView.convert(tapLocation, toCoordinateFrom: mapView) // 手动构建CLPlacemark的必要参数 let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude) let region = CLRegion(center: coordinate, radius: 50, identifier: "tapRegion") let addressDict = [CNPostalAddressStreetKey: "测试街道"] as [String: Any] // 使用指定初始化器创建实例 if let tapLocationPlacemark = CLPlacemark( coordinate: coordinate, postalAddress: nil, location: location, region: region, addressDictionary: addressDict ) { // 在这里使用合法的placemark } default: break } }
重要提醒
- 永远不要直接调用
CLPlacemark()初始化,这属于框架未公开的未定义行为,必然会导致各种内存问题。 - 反向地理编码是异步操作,记得用
[weak self]避免循环引用,同时要处理错误情况(比如网络问题、无法解析坐标等)。
内容的提问来源于stack exchange,提问作者Teodor Afrim
相关产品推荐
相关产品推荐

