Расширение CLPlacemark приводит к EXC BAD ACCESS
Хотя здесь есть похожий вопрос, он не дает ответа, по крайней мере, не для общей проблемы.
Моя проблема: с CoreLocation
геокодирование ограничено по скорости, и (веб-) служба, для которой я разрабатываю приложение, предоставляет собственную резервную службу геокодирования, я хочу использовать эту специальную службу геокодирования на случай, если я достигну предела скорости Apple. Кроме того, я считаю, что имеет смысл избегать использования пользовательского типа данных для результатов, возвращаемых этим пользовательским REST API, и поэтому хотел бы использовать данные, возвращаемые для создания CLPlacemark
s. Однако в документации говорится, что CLPlacemark
свойства, такие как location, locality, administrativeArea
и т. д. read-only
, Поэтому я создал подкласс CLPlacemark
синтезировать необходимые свойства на частные переменные, к которым я могу получить доступ, то есть:
// interface: (.h)
@interface CustomPlacemark : CLPlacemark
- (nonnull id)initWithLocation: (nonnull CLLocation *)location
locality: (nullable NSString *)locality
administrativeArea: (nullable NSString *)adminArea
country: (nullable NSString *)country;
@end
// implementation (.m)
@implementation CustomPlacemark
@synthesize location = _location;
@synthesize locality = _locality;
@synthesize country = _country;
@synthesize administrativeArea = _administrativeArea;
- (nonnull id)initWithLocation: (nonnull CLLocation *)location
locality: (nullable NSString *)locality
administrativeArea: (nullable NSString *)adminArea
country: (nullable NSString *)country{
self = [super init];
if(self){
_location = location;
_locality = locality;
_administrativeArea = adminArea;
_country = country;
}
return self;
}
@end
Тестирование этого кода с помощью модульного теста, который анализирует данные из файла JSON и вызывает мой initWithLocation: locality: administrativeArea: country:
Метод с данными приводит к EXC BAD ACCESS (code=1)
в конце теста (при закрытии }
метода тестирования) с переменной метки, указывающей на nil
хотя до NSLog(@"placemark: %@", customPlacemark);
выводит правильные значения. Кроме того, шаг за шагом тестирование показывает CustomPlacemark
работать (т.е. указывать на правильно заполненный объект) до достижения конца теста. Для меня это указывает на то, что что-то с освобождением моего CustomPlacemark
идет не так - но что именно?
Любая помощь очень ценится!
1 ответ
Как ссылка на любого приземляющегося здесь с похожей проблемой:
После некоторого интенсивного Google-Fu и глубокого погружения в источники Apple, кажется, что расширение CLPlacemark
не предназначен.
Я, однако, смог реализовать обходной путь на основе советов, найденных здесь, который в основном злоупотребляет тем фактом, что MKPlacemark
продолжается CLPlacemark
и предлагает метод для инициализации с пользовательскими данными, а именно - (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary<NSString *, id> * _Nullable)addressDictionary
, Нахождение правильных ключей для addressDictionary
для сопоставления желаемых свойств в CLPlacemark
может потребовать проб и ошибок, тем более что ABPerson/Address
функциональность стала устаревшей с iOS 9. Ключи, которые я нашел для моих целей:
@"City" -> CLPlacemark.city
@"State" -> CLPlacemark.administrativeArea
@"Country" -> CLPlacemark.country
Спасибо @hpd!
Мой быстрый макет класса:
class TestPlacemark: CLPlacemark {
static let coordinate = CLLocationCoordinate2D(latitude: CLLocationDegrees(35), longitude: CLLocationDegrees(-80))
override init() {
let mkPlacemark = MKPlacemark(coordinate: TestPlacemark.coordinate) as CLPlacemark
super.init(placemark: mkPlacemark)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override static var supportsSecureCoding: Bool {
return false
}
override var location: CLLocation? {
return CLLocation(latitude: TestPlacemark.coordinate.latitude, longitude: TestPlacemark.coordinate.longitude)
}
override var postalAddress: CNPostalAddress? {
return TestPostalAddress()
}
}
Надеюсь, это сэкономит время кому-то еще. Ура!