扩展CLPlacemark会导致EXC BAD ACCESS [英] Extending CLPlacemark results in EXC BAD ACCESS

查看:137
本文介绍了扩展CLPlacemark会导致EXC BAD ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管有类似的问题,但这里它没有提供答案,至少不是一般问题。

Though there is a similar question found here it does not provide an answer, at least not for the general problem.

我的问题是:
由于 CoreLocation 地理编码是速率限制的,我正在开发应用程序的(网络)服务提供自己的后备地理编码服务,我想使用这个自定义地理编码服务,以防我达到Apple的速率限制。此外,我觉得避免使用此自定义REST API返回的结果的自定义数据类型是完全有意义的,因此希望使用返回的数据生成 CLPlacemark s。但是,文档说明 CLPlacemark 属性,例如 location,locality,administrativeArea 只读
因此我创建了一个 CLPlacemark 的子类,将所需的属性合成到我可以访问的私有变量上,即:

My problem is: Since CoreLocation geocoding is rate limited and the (web-)service I am developing an app for provides its own fallback geocoding service, I want to use this custom geocoding service in case I reach Apple's rate limit. Furthermore, I feel it makes total sense to avoid a custom data type for results returned by this custom REST API and therefore would like to use the data returned to generate CLPlacemarks. However, the documentation states that CLPlacemark properties such as location, locality, administrativeArea etc. are read-only. I therefore created a subclass of CLPlacemark synthesizing the needed properties onto private variables I can access, i.e.:

// 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 的重新分配出错 - 但究竟是什么?

Testing this code with a unit test which parses data from a JSON file and calls my initWithLocation: locality: administrativeArea: country: method with the data results in a EXC BAD ACCESS (code=1) at the end of the test (at the closing } of the test method) with the placemark variable pointing to nil although a prior NSLog(@"placemark: %@", customPlacemark); outputs the correct values. Furthermore, stepping through the test line by line shows the CustomPlacemark working (i.e. pointing to a properly populated object) until reaching the end of the test. To me this indicates that something with the deallocation of my CustomPlacemark goes wrong - but what exactly?

任何帮助都是非常感谢!

Any help is greatly appreciated!

推荐答案

作为对这里遇到类似问题的人的参考:

As a reference to anyone landing here with a similar problem:

在一些密集的Google-Fu和深入潜入Apple的消息来源之后,好像无法扩展 CLPlacemark

After some intensive Google-Fu and deep diving into Apple's sources, it seems as if extending CLPlacemark is not intended.

然而,我能够根据找到的提示实施解决方法这里,基本上滥用 MKPlacemark 扩展 CLPlacemark 并提供了一个使用自定义数据初始化的方法,即 - (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)坐标地址字典:(NSDictionary< NSString *,id> * _Nullable)addressDictionary 。找到 addressDictionary 的正确键以映射 CLPlacemark 中的所需属性可能需要一些试验和错误,尤其是因为 ABPerson /地址功能已被iOS 9弃用。
我找到的密钥是:

I was, however, able to implement a workaround based on the tips found here, which basically abuses the fact that MKPlacemark extends CLPlacemark and offers a method to initialise with custom data, namely - (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary<NSString *, id> * _Nullable)addressDictionary. Finding the right keys for the addressDictionary to map the desired properties in CLPlacemark might require some trial and error, especially since ABPerson/Addressfunctionality has become deprecated with iOS 9. The keys I found for my purposes are:

@"City" -> CLPlacemark.city
@"State" -> CLPlacemark.administrativeArea
@"Country" -> CLPlacemark.country

这篇关于扩展CLPlacemark会导致EXC BAD ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆