Так что у вас есть проблема времени. Вызов reverseGeocodeLocation:completionHandler:
является асинхронным . Сам вызов будет возвращен непосредственно перед тем, как произойдет реальная обратная геолокация.
Таким образом, сразу после возврата вызова ваш метод продолжается, и вы создаете аннотацию с меткой, которой еще не существует.
Затем , через некоторое время , ваша обратная геолокация завершена (помните, что для этого требуется сетевой вызов службы и все такое). А затем после этого ваш блок запускается с новыми входящими данными.
Таким образом, к тому моменту, когда ваш блок действительно выполняется, эти две локальные переменные __block, которые вы создали, уже давно исчезли. Зачем? Поскольку эти переменные placemark
и sPlacemark
являются локальными (автоматическими) переменными, локальными для этого метода. Они возникают внутри метода, а затем уходят, когда метод завершается. И опять же, это происходит еще до того, как ваш блок заработает. (Оказывается, блок позже запишет в копию каждой переменной, но это не имеет значения, потому что этот метод уже завершен, и вы уже пытались прочитать их слишком рано.)
Если вы поместите сообщение NSLog в конце этого метода, а другое - в своем блоке, вы увидите последовательность, в которой они запускаются. Порядок будет противоположен тому, что вы, вероятно, думаете. Сначала сработает тот, что в конце метода, а затем тот, что находится внутри блока.
Думайте об этом как о ресторане. Официант возвращается на кухню и размещает заказ. Теперь он не сидит на кухне и не ждет, пока приготовится еда, потому что это занимает время. Поэтому он оставляет заказ и продолжает свою работу до тех пор, пока заказ не будет готов. Теперь представьте, что он оставляет заказ, а затем немедленно проверяет счетчик. Он будет очень разочарован, увидев, что еды еще нет. И это именно то, что вы делаете, когда сразу пытаетесь прочитать переменную placemark
до того, как у поваров будет хотя бы секунда, чтобы приготовить заказ.
Так каков ответ? Вы можете создать другой метод, который создает аннотацию и размещает ее на карте. Этот метод должен принимать метку в качестве параметра, и затем вы можете вызывать этот метод изнутри блока (что опять-таки происходит после того, как у вас действительно есть метка). Думайте об этом как о всей работе, которую официант хотел бы выполнить после заказ готов, как и прием заказа у клиента.
Есть и другие способы сделать это. Но для одной метки, как вы показываете здесь, это простой способ справиться с этим. Очевидно, что вам также следует добавить обработку ошибок, если вы не можете найти метку или служба недоступна и т. Д. Если поиск не удастся, метка будет нулевой, и вы можете проверить ошибку для получения дополнительной информации.
Надеюсь, это поможет.