扩展CLPlacemark结果导致EXC错误访问权限

问题描述 投票:2回答:2

尽管发现了一个类似的问题here,但它没有提供答案,至少对于一般问题没有提供答案。

我的问题是:由于CoreLocation地理编码受速率限制,并且我正在开发的应用程序提供的(网络)服务提供了自己的后备地理编码服务,因此,在我达到Apple的速率限制时,我想使用此自定义地理编码服务。此外,我觉得避免为此自定义REST API返回的结果使用自定义数据类型是完全有意义的,因此我想使用返回的数据来生成CLPlacemark。但是,文档指出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的重新分配出现了问题-但是究竟是什么?

非常感谢您的帮助!

ios objective-c core-location extend clplacemark
2个回答
6
投票

作为对在这里着陆的类似问题的参考:

[经过大量的Google-Fu并深入研究了Apple的资源之后,似乎似乎并没有打算扩展CLPlacemark

但是,我能够根据发现的here技巧实施变通方法,这基本上滥用了MKPlacemark扩展CLPlacemark并提供一种使用自定义数据初始化的方法,即- (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary<NSString *, id> * _Nullable)addressDictionary的事实。为addressDictionary查找正确的键以在CLPlacemark中映射所需的属性可能需要反复试验,尤其是因为iOS 9已弃用ABPerson/Address功能。我发现用于我的目的的键是:

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

0
投票

谢谢@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()
    }
}

希望它可以节省其他人的时间。干杯!

© www.soinside.com 2019 - 2024. All rights reserved.