Выполнение HTTP-запроса с AlamoFire вызывает EXC_BAD_ACCESS

Я работаю над простым проектом, чтобы помочь изучить Swift, и я столкнулся с проблемой, которая, как мне кажется, имеет более глубокие последствия/возможности обучения (пытаясь смотреть на светлую сторону).

Проблема высокого уровня заключается в том, что когда я отправляю параметры в кодировке JSON с помощью AlamoFire, ошибка EXC_BAD_ACCESS быстро появляется в отдельной строке кода, где я устанавливаю один из параметров (в частности, "didUpdateLocations" CoreLocation Manager)... вот код:

В ViewController я создаю изменяемый словарь:

var parameters = [String:AnyObject]()

А для события didUpdateLocations я присваиваю обновленные значения широты/долготы соответствующим ключам в изменяемом словаре.

class ViewController: UIViewController, CLLocationManagerDelegate {
    let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    ...
    func locationManager(locManager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
        appDelegate.parameters["longitude"] = locManager.location.coordinate.longitude
        appDelegate.parameters["latitude"] = locManager.location.coordinate.latitude
    }

Наконец, у меня есть периодическая функция (использующая NSTimer.scheduledTimerWithTimeInterval), которая отправляет POST на сервер.

func updatePost() {
    println("POSTing update")

    Alamofire.request(.POST, "http://server.co/endpoint",
            parameters: appDelegate.parameters, encoding: .JSON)
}

Если я закомментирую сообщение Alamofire POST, все будет в порядке. С POST я получаю ошибку EXC_BAD_ACCESS в первой строке didUpdateLocations (где установлен ключ longitude)

Я подозреваю, что это как-то связано с тем, как параметры преобразуются процедурой кодирования Alamofire, но я понятия не имею, почему это может появиться в функции didUpdateLocations, а не в самом вызове Alamofire...

Может ли кто-нибудь дать какие-либо идеи? Спасибо


person Dan    schedule 06.12.2014    source источник
comment
Почему вы так все кладете в AppDelegate? Глобальное общее изменяемое состояние — это рецепт для EXC_BAD_ACCESS и других ошибок владения.   -  person mattt    schedule 06.12.2014
comment
Это была задержка формы, которую я пробовал ранее, но хорошая мысль. Я только что переместил parameters в ViewController, и возникает та же проблема.   -  person Dan    schedule 06.12.2014


Ответы (1)


Происходит то, что у вас есть несколько потоков, пытающихся одновременно получить доступ к Dictionary. Когда вы изменяете parameters в didUpdateLocations, он, скорее всего, перемещается в памяти во время чтения внутри Alamofire, вызывая исключение EXC_BAD_ACCESS.

Чтобы решить эту проблему, я бы прекратил обновлять словарь parameters из didUpdateLocations - вместо этого добавьте свойство latestLocation в ваш контроллер представления и обновите его. Затем внутри updatePost создайте свой словарь параметров и передайте его Alamofire.request.

person Nate Cook    schedule 06.12.2014
comment
Это логично - спасибо! Предлагаемое решение сработало - person Dan; 06.12.2014