Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

470
Visualizações
How to solve std::bad_alloc exception swift iOS?

I need accurate location. To achieve the goal I have used like the below logic:

  1. I am trying to check updated location is to be accurate, if it is accurate then return it.
  2. But sometimes app does not receive accurate location(especially inside forest or between tall buildings, ...) for long time. To solve this I have put 5 second threshold time. If app doesn't receive accurate location for 5 seconds, app applies the latest tracked location even if it is not accurate.

So in my code timer will start/stop inside didUpdateLocations method multiple times.

But it is crashed randomly. Here is crash info:

libc++abi: terminating with uncaught exception of type std::bad_alloc: std::bad_alloc
dyld4 config: DYLD_LIBRARY_PATH=/usr/lib/system/introspection DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/usr/lib/libMTLCapture.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib
terminating with uncaught exception of type std::bad_alloc: std::bad_alloc

enter image description here

enter image description here

enter image description here

Here is my full code:

import UIKit
import CoreLocation

final class MapView: UIView {
    private lazy var locationImprover = TimerBasedLocationImprover(acceptInitialLocation: true) {[weak self] location in
        self?.updatedLocation(location)
    }
    
    private lazy var locationManager = CLLocationManager()
    
    init() {
        super.init(frame: .zero)
        setup()
    }
      
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    deinit {
        stopUpdating()
    }
    
    private func setup() {
        setupLocationManager()
    }
    
    private func setupLocationManager() {
        locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation
        locationManager.distanceFilter = 1
        
        locationManager.delegate = self
        
        locationManager.requestWhenInUseAuthorization()
        startUpdating(manager: locationManager)
    }
    
    private func startUpdating(manager: CLLocationManager) {
        if CLLocationManager.locationServicesEnabled() {
          manager.startUpdatingLocation()
        }
        
        if CLLocationManager.headingAvailable() {
          manager.startUpdatingHeading()
        }
    }
      
    func stopUpdating() {
        locationManager.stopUpdatingLocation()
        locationManager.stopUpdatingHeading()
    }
        
    private func updatedLocation(_ location: CLLocation) {
        //Some UI update
    }

}

extension MapView: CLLocationManagerDelegate {
  func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    startUpdating(manager: manager)
  }
  
  func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    startUpdating(manager: manager)
  }
  
  func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let lastLocation = locations.last,
          let improvedLocation = locationImprover.improved(location: lastLocation) else { return }
    
    updatedLocation(improvedLocation)
  }
  
  func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
    guard newHeading.headingAccuracy > 0 else { return }
  }
}


final class TimerBasedLocationImprover {
    private var _lastLocation: CLLocation?
    private let lastLocationLock = NSLock()
    private var lastLocation: CLLocation? {
        get {
            defer { lastLocationLock.unlock() }
            lastLocationLock.lock()
            return _lastLocation
        }
        set {
            lastLocationLock.lock()
            _lastLocation = newValue
            lastLocationLock.unlock()
        }
    }
    
    private var _workItem: DispatchWorkItem?
    private let workItemLock = NSLock()
    private var workItem: DispatchWorkItem? {
        get {
            defer { workItemLock.unlock() }
            workItemLock.lock()
            return _workItem
        }
        set {
            workItemLock.lock()
            _workItem = newValue
            workItemLock.unlock()
        }
    }
    
    private let timerThreashold: TimeInterval
    private let acceptInitialLocation: Bool
    private let onReachThreashold: (CLLocation) -> Void
    init(timerThreashold: TimeInterval = 5,
         acceptInitialLocation: Bool,
         onReachThreashold: @escaping (CLLocation) -> Void) {
        self.timerThreashold = timerThreashold
        self.acceptInitialLocation = acceptInitialLocation
        self.onReachThreashold = onReachThreashold
        
        startTimer()
    }
    
    deinit {
        stopTimer()
    }
    
    func improved(location: CLLocation) -> CLLocation? {
        debugPrint("improved thread is main: \(Thread.isMainThread)")
        
        if lastLocation == nil,
           acceptInitialLocation {
            startTimer()
            lastLocation = location
            startTimer()
            return location
        }
        
        lastLocation = location
        
        guard location.isAccurate else { return nil }
        
        startTimer()
        
        return location
    }
  
    private func startTimer() {
        debugPrint("startTimer thread is main: \(Thread.isMainThread)")
        stopTimer()
        
        let wi = DispatchWorkItem() {[weak self] in
            self?.timerDone()
        }
        
        DispatchQueue.global(qos: .background)
            .asyncAfter(deadline: .now() + timerThreashold,
                        execute: wi)
        
        workItem = wi
    }
    
    private func stopTimer() {
        workItem?.cancel()
        workItem = nil
    }
    
    private func timerDone() {
        if let lastLocation = lastLocation {
            DispatchQueue.main.async {
                self.onReachThreashold(lastLocation)
            }
        }
        startTimer()
    }
}

extension CLLocation {
    var isAccurate: Bool {
        horizontalAccuracy > 0 && horizontalAccuracy > 20
    }
}

over 4 years ago · Santiago Trujillo
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda