2

虽然在这里找到了一个类似的问题,但它没有提供答案,至少不是针对一般问题。

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

任何帮助是极大的赞赏!

4

2 回答 2

7

作为对遇到类似问题的任何人的参考:

经过一些密集的 Google-Fu 和深入研究 Apple 的资源之后,似乎CLPlacemark没有打算进行扩展。

但是,我能够根据此处MKPlacemark找到的提示实现一种解决方法,它基本上滥用了扩展的事实,CLPlacemark并提供了一种使用自定义数据进行初始化的方法,即- (instancetype _Nonnull)initWithCoordinate:(CLLocationCoordinate2D)coordinate addressDictionary:(NSDictionary<NSString *, id> * _Nullable)addressDictionary. 找到正确的键addressDictionary来映射所需的属性CLPlacemark可能需要一些试验和错误,特别是因为ABPerson/AddressiOS 9 已弃用功能。我为我的目的找到的键是:

@"City" -> CLPlacemark.city
@"State" -> CLPlacemark.administrativeArea
@"Country" -> CLPlacemark.country
于 2015-09-19T16:52:20.993 回答
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()
    }
}

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

于 2020-05-08T05:58:34.543 回答